[{"data":1,"prerenderedAt":11800},["Reactive",2],{"navigation":3,"aAII9Cz3yR":204,"tags-Azure Active Directory":397},[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",[205,207,209,211,214,217,220,223,226,229,231,234,237,240,242,244,247,250,253,255,258,261,264,267,270,273,276,279,282,285,287,289,292,294,297,300,303,305,308,310,313,316,319,322,325,327,329,332,335,338,341,344,347,350,353,356,359,361,363,366,369,372,375,377,380,383,385,388,391,394],[206,206],"tooling",[208,208],"vscode",[210,210],"rest",[212,213],"http","HTTP",[215,216],"razor","Razor",[218,219],"xamarin","Xamarin",[221,222],"templating","Templating",[224,225],"azure-cli","Azure CLI",[227,228],"azure","Azure",[230,230],"shell",[232,233],"github","GitHub",[235,236],"asp-net-core","ASP.NET Core",[238,239],"net",".NET",[241,241],"git",[243,243],"nushell",[245,246],"microsoft-teams","Microsoft Teams",[248,249],"powershell","PowerShell",[251,252],"azure-active-directory","Azure Active Directory",[254,254],"learning",[256,257],"azure-functions","Azure Functions",[259,260],"azure-key-vault","Azure Key Vault",[262,263],"configuration","Configuration",[265,266],"devops","DevOps",[268,269],"it","IT",[271,272],"tips-learned-this-week","tips learned this week",[274,275],"windows-terminal","Windows Terminal",[277,278],"azure-pipelines","Azure Pipelines",[280,281],"application-insights","Application Insights",[283,284],"azure-iot","Azure IoT",[286,286],"records",[288,288],"refit",[290,291],"development-box-setup","development box setup",[293,293],"winget",[295,296],"package-manager","package manager",[298,299],"azure-sql-database","Azure SQL Database",[301,302],"azure-sdk","Azure SDK",[304,304],"wingetcreate",[306,307],"github-actions","GitHub Actions",[309,309],"jq",[311,312],"pulumi","Pulumi",[314,315],"iac","IaC",[317,318],"azure-storage","Azure Storage",[320,321],"azure-signalr","Azure SignalR",[323,324],"visio","Visio",[326,326],"csharp",[328,328],"jest",[330,331],"statiq","Statiq",[333,334],"open-source","open source",[336,337],"visual-studio","Visual Studio",[339,340],"vue-js","Vue.js",[342,343],"azure-devops","Azure DevOps",[345,346],"vite","Vite",[348,349],"code-analysis","Code analysis",[351,352],"diagram","Diagram",[354,355],"terraform","Terraform",[357,358],"typescript","TypeScript",[360,360],"thoughts",[362,362],"pnpm",[364,365],"nuke","Nuke",[367,368],"pipelines","Pipelines",[370,371],"cicd","CI/CD",[373,374],"openid-connect","OpenID Connect",[376,376],"security",[378,379],"github-cli","GitHub CLI",[381,382],"microsoft-entra-id","Microsoft Entra ID",[384,384],"advent",[386,387],"finops","FinOps",[389,390],"anglesharp","AngleSharp",[392,393],"oauth2","OAuth2",[395,396],"azure-ad-b2c","Azure AD B2C",[398,3391,5379,7795],{"_path":112,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":111,"description":402,"lead":403,"date":404,"image":405,"badge":407,"tags":408,"body":409,"_type":3386,"_id":3387,"_source":3388,"_file":3389,"_extension":3390},"posts",false,"","In this article, we will talk about how to provision an Azure SQL Database with authentication restricted to Active Directory users/groups/applications. We will use Pulumi to do that.","Using Pulumi and its command provider to grant database permissions","2022-02-22T00:00:00.000Z",{"src":406},"/images/lockers_1.jpg",{"label":266},[252,299,228,239,312,315],{"type":410,"children":411,"toc":3368},"root",[412,419,426,451,465,475,480,486,491,804,834,840,845,1160,1172,1364,1370,1375,1388,1491,1512,1517,1522,1550,1555,1562,1576,1588,1620,1629,1645,1657,1663,1691,1696,1709,1831,1843,1875,1887,1926,1935,1962,2017,2023,2042,2048,2061,2140,2173,2178,2345,2351,2356,2538,2543,2561,2567,2586,2675,2687,2846,2867,2872,3258,3263,3296,3302,3320,3329,3335,3347,3352,3357,3362],{"type":413,"tag":414,"props":415,"children":416},"element","p",{},[417],{"type":418,"value":402},"text",{"type":413,"tag":420,"props":421,"children":423},"h2",{"id":422},"why-this-article",[424],{"type":418,"value":425},"Why this article?",{"type":413,"tag":414,"props":427,"children":428},{},[429,431,440,442,449],{"type":418,"value":430},"In ",{"type":413,"tag":432,"props":433,"children":437},"a",{"href":434,"rel":435},"https://www.techwatching.dev/posts/sqlclient-active-directory-authent",[436],"nofollow",[438],{"type":418,"value":439},"a previous article",{"type":418,"value":441},", I already talked about connecting to an Azure SQL Database using Azure Active Directory authentication. However, my focus was on querying an Azure SQL Database from C# code (from an ASP.NET 6 Minimal API that was using ",{"type":413,"tag":443,"props":444,"children":446},"code",{"className":445},[],[447],{"type":418,"value":448},"Microsoft.Data.SqlClient",{"type":418,"value":450}," 'Active Directory Default' authentication mode to be more precise), and not on the configuration of the Azure AD authentication itself.",{"type":413,"tag":414,"props":452,"children":453},{},[454,456,463],{"type":418,"value":455},"Still, in that article, I wrote an Azure CLI script that showed how to provision and configure the database with Azure AD authentication enabled. So why write another article about that? First because I did not show how to give an Azure AD entity (user, group, or managed identity) permission to access the database. (In my samples, to simplify things I was using the SQL server Azure AD administrator account to make my queries 🤫). Yet, it is something you will probably have to do if you want your App Service or Function App to query your database. Second because even if Azure CLI is great to handle Azure resources (if you are a reader of my blog, you probably know that I ",{"type":413,"tag":432,"props":457,"children":460},{"href":458,"rel":459},"https://www.techwatching.dev/posts/welcome-azure-cli",[436],[461],{"type":418,"value":462},"enjoy very much Azure CLI",{"type":418,"value":464},"), in a real project I would probably use a more advanced Infrastructure as Code solution like Pulumi. And that is what we will show here.",{"type":413,"tag":466,"props":467,"children":469},"callout",{"icon":468},"i-heroicons-chat-bubble-left-20-solid",[470],{"type":413,"tag":414,"props":471,"children":472},{},[473],{"type":418,"value":474},"If you are not familiar with Pulumi, it is an IaC solution similar to Terraform but using programming languages like C#. Speaking of C#, that is what I will use to write my infrastructure code but you can easily do the same in another language supported by Pulumi (TypeScript, Go, Python,... choose the one you are used to), the concepts stay relevant and the code will be similar.",{"type":413,"tag":414,"props":476,"children":477},{},[478],{"type":418,"value":479},"Now, let's get to the heart of the matter.",{"type":413,"tag":420,"props":481,"children":483},{"id":482},"an-azure-ad-user-as-our-sql-server-administrator",[484],{"type":418,"value":485},"An Azure AD user as our SQL Server administrator",{"type":413,"tag":414,"props":487,"children":488},{},[489],{"type":418,"value":490},"Usually, when you create an Azure SQL Server, you have to provide an administrator login and an administrator password. But I said I wanted to limit the authentication to Azure Active Directory authentication only. So we will only need an Azure AD account to set as the administrator of our SQL Server. We could use an existing Azure AD account, but let's create a new Azure AD user just for that:",{"type":413,"tag":492,"props":493,"children":496},"pre",{"className":494,"code":495,"language":326,"meta":401,"style":401},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","var config = new Config();\nvar sqlAdAdminLogin = config.Require(\"sqlAdAdmin\");\nvar sqlAdAdminPassword = config.RequireSecret(\"sqlAdPassword\");\n\nvar sqlAdAdmin = new User(\"sqlAdmin\", new UserArgs\n{\n    UserPrincipalName = sqlAdAdminLogin,\n    Password = sqlAdAdminPassword,\n    DisplayName = \"Global SQL Admin\"\n});\n",[497],{"type":413,"tag":443,"props":498,"children":499},{"__ignoreMap":401},[500,538,596,647,657,714,723,746,767,795],{"type":413,"tag":501,"props":502,"children":505},"span",{"class":503,"line":504},"line",1,[506,512,517,523,528,533],{"type":413,"tag":501,"props":507,"children":509},{"style":508},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[510],{"type":418,"value":511},"var",{"type":413,"tag":501,"props":513,"children":514},{"style":508},[515],{"type":418,"value":516}," config",{"type":413,"tag":501,"props":518,"children":520},{"style":519},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[521],{"type":418,"value":522}," =",{"type":413,"tag":501,"props":524,"children":525},{"style":519},[526],{"type":418,"value":527}," new",{"type":413,"tag":501,"props":529,"children":530},{"style":508},[531],{"type":418,"value":532}," Config",{"type":413,"tag":501,"props":534,"children":535},{"style":519},[536],{"type":418,"value":537},"();\n",{"type":413,"tag":501,"props":539,"children":541},{"class":503,"line":540},2,[542,546,551,555,560,565,571,576,581,587,591],{"type":413,"tag":501,"props":543,"children":544},{"style":508},[545],{"type":418,"value":511},{"type":413,"tag":501,"props":547,"children":548},{"style":508},[549],{"type":418,"value":550}," sqlAdAdminLogin",{"type":413,"tag":501,"props":552,"children":553},{"style":519},[554],{"type":418,"value":522},{"type":413,"tag":501,"props":556,"children":558},{"style":557},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[559],{"type":418,"value":516},{"type":413,"tag":501,"props":561,"children":562},{"style":519},[563],{"type":418,"value":564},".",{"type":413,"tag":501,"props":566,"children":568},{"style":567},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[569],{"type":418,"value":570},"Require",{"type":413,"tag":501,"props":572,"children":573},{"style":519},[574],{"type":418,"value":575},"(",{"type":413,"tag":501,"props":577,"children":578},{"style":519},[579],{"type":418,"value":580},"\"",{"type":413,"tag":501,"props":582,"children":584},{"style":583},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[585],{"type":418,"value":586},"sqlAdAdmin",{"type":413,"tag":501,"props":588,"children":589},{"style":519},[590],{"type":418,"value":580},{"type":413,"tag":501,"props":592,"children":593},{"style":519},[594],{"type":418,"value":595},");\n",{"type":413,"tag":501,"props":597,"children":599},{"class":503,"line":598},3,[600,604,609,613,617,621,626,630,634,639,643],{"type":413,"tag":501,"props":601,"children":602},{"style":508},[603],{"type":418,"value":511},{"type":413,"tag":501,"props":605,"children":606},{"style":508},[607],{"type":418,"value":608}," sqlAdAdminPassword",{"type":413,"tag":501,"props":610,"children":611},{"style":519},[612],{"type":418,"value":522},{"type":413,"tag":501,"props":614,"children":615},{"style":557},[616],{"type":418,"value":516},{"type":413,"tag":501,"props":618,"children":619},{"style":519},[620],{"type":418,"value":564},{"type":413,"tag":501,"props":622,"children":623},{"style":567},[624],{"type":418,"value":625},"RequireSecret",{"type":413,"tag":501,"props":627,"children":628},{"style":519},[629],{"type":418,"value":575},{"type":413,"tag":501,"props":631,"children":632},{"style":519},[633],{"type":418,"value":580},{"type":413,"tag":501,"props":635,"children":636},{"style":583},[637],{"type":418,"value":638},"sqlAdPassword",{"type":413,"tag":501,"props":640,"children":641},{"style":519},[642],{"type":418,"value":580},{"type":413,"tag":501,"props":644,"children":645},{"style":519},[646],{"type":418,"value":595},{"type":413,"tag":501,"props":648,"children":650},{"class":503,"line":649},4,[651],{"type":413,"tag":501,"props":652,"children":654},{"emptyLinePlaceholder":653},true,[655],{"type":418,"value":656},"\n",{"type":413,"tag":501,"props":658,"children":660},{"class":503,"line":659},5,[661,665,670,674,678,683,687,691,696,700,705,709],{"type":413,"tag":501,"props":662,"children":663},{"style":508},[664],{"type":418,"value":511},{"type":413,"tag":501,"props":666,"children":667},{"style":508},[668],{"type":418,"value":669}," sqlAdAdmin",{"type":413,"tag":501,"props":671,"children":672},{"style":519},[673],{"type":418,"value":522},{"type":413,"tag":501,"props":675,"children":676},{"style":519},[677],{"type":418,"value":527},{"type":413,"tag":501,"props":679,"children":680},{"style":508},[681],{"type":418,"value":682}," User",{"type":413,"tag":501,"props":684,"children":685},{"style":519},[686],{"type":418,"value":575},{"type":413,"tag":501,"props":688,"children":689},{"style":519},[690],{"type":418,"value":580},{"type":413,"tag":501,"props":692,"children":693},{"style":583},[694],{"type":418,"value":695},"sqlAdmin",{"type":413,"tag":501,"props":697,"children":698},{"style":519},[699],{"type":418,"value":580},{"type":413,"tag":501,"props":701,"children":702},{"style":519},[703],{"type":418,"value":704},",",{"type":413,"tag":501,"props":706,"children":707},{"style":519},[708],{"type":418,"value":527},{"type":413,"tag":501,"props":710,"children":711},{"style":508},[712],{"type":418,"value":713}," UserArgs\n",{"type":413,"tag":501,"props":715,"children":717},{"class":503,"line":716},6,[718],{"type":413,"tag":501,"props":719,"children":720},{"style":519},[721],{"type":418,"value":722},"{\n",{"type":413,"tag":501,"props":724,"children":726},{"class":503,"line":725},7,[727,732,737,741],{"type":413,"tag":501,"props":728,"children":729},{"style":557},[730],{"type":418,"value":731},"    UserPrincipalName ",{"type":413,"tag":501,"props":733,"children":734},{"style":519},[735],{"type":418,"value":736},"=",{"type":413,"tag":501,"props":738,"children":739},{"style":557},[740],{"type":418,"value":550},{"type":413,"tag":501,"props":742,"children":743},{"style":519},[744],{"type":418,"value":745},",\n",{"type":413,"tag":501,"props":747,"children":749},{"class":503,"line":748},8,[750,755,759,763],{"type":413,"tag":501,"props":751,"children":752},{"style":557},[753],{"type":418,"value":754},"    Password ",{"type":413,"tag":501,"props":756,"children":757},{"style":519},[758],{"type":418,"value":736},{"type":413,"tag":501,"props":760,"children":761},{"style":557},[762],{"type":418,"value":608},{"type":413,"tag":501,"props":764,"children":765},{"style":519},[766],{"type":418,"value":745},{"type":413,"tag":501,"props":768,"children":770},{"class":503,"line":769},9,[771,776,780,785,790],{"type":413,"tag":501,"props":772,"children":773},{"style":557},[774],{"type":418,"value":775},"    DisplayName ",{"type":413,"tag":501,"props":777,"children":778},{"style":519},[779],{"type":418,"value":736},{"type":413,"tag":501,"props":781,"children":782},{"style":519},[783],{"type":418,"value":784}," \"",{"type":413,"tag":501,"props":786,"children":787},{"style":583},[788],{"type":418,"value":789},"Global SQL Admin",{"type":413,"tag":501,"props":791,"children":792},{"style":519},[793],{"type":418,"value":794},"\"\n",{"type":413,"tag":501,"props":796,"children":798},{"class":503,"line":797},10,[799],{"type":413,"tag":501,"props":800,"children":801},{"style":519},[802],{"type":418,"value":803},"});\n",{"type":413,"tag":414,"props":805,"children":806},{},[807,809,815,817,823,825,832],{"type":418,"value":808},"To create a new Azure AD user we need a login (it will be the email of the new user in our tenant) and a password. In this example, we retrieve these values from the ",{"type":413,"tag":432,"props":810,"children":813},{"href":811,"rel":812},"https://www.pulumi.com/docs/intro/concepts/config/",[436],[814],{"type":418,"value":262},{"type":418,"value":816}," which is stored in the YAML settings file. You can notice there that we retrieve a secret (the password) from the configuration thanks to the ",{"type":413,"tag":443,"props":818,"children":820},{"className":819},[],[821],{"type":418,"value":822},"config.RequireSecret",{"type":418,"value":824}," method. Indeed to avoid exposing a secret in the configuration file or the state file, Pulumi has ",{"type":413,"tag":432,"props":826,"children":829},{"href":827,"rel":828},"https://www.pulumi.com/docs/intro/concepts/secrets/",[436],[830],{"type":418,"value":831},"built-in support for secret encryption and decryption",{"type":418,"value":833}," (not sure Terraform folks can say the same thing 😉).",{"type":413,"tag":420,"props":835,"children":837},{"id":836},"create-the-azure-sql-server-and-its-database",[838],{"type":418,"value":839},"Create the Azure SQL Server and its database.",{"type":413,"tag":414,"props":841,"children":842},{},[843],{"type":418,"value":844},"Now that we have our administrator account, we can create the Azure SQL Server:",{"type":413,"tag":492,"props":846,"children":848},{"className":494,"code":847,"language":326,"meta":401,"style":401},"var sqlServer = new Server($\"sql-sqlDbWithAzureAd-{Deployment.Instance.StackName}\", new ServerArgs\n{\n    ResourceGroupName = resourceGroup.Name,\n    Administrators = new ServerExternalAdministratorArgs\n    {\n        Login = sqlAdAdmin.UserPrincipalName,\n        Sid = sqlAdAdmin.Id,\n        AzureADOnlyAuthentication = true,\n        AdministratorType = AdministratorType.ActiveDirectory,\n        PrincipalType = PrincipalType.User,\n    },\n});\n",[849],{"type":413,"tag":443,"props":850,"children":851},{"__ignoreMap":401},[852,937,944,974,995,1003,1032,1061,1083,1113,1143,1152],{"type":413,"tag":501,"props":853,"children":854},{"class":503,"line":504},[855,859,864,868,872,877,881,886,891,896,901,905,910,914,919,924,928,932],{"type":413,"tag":501,"props":856,"children":857},{"style":508},[858],{"type":418,"value":511},{"type":413,"tag":501,"props":860,"children":861},{"style":508},[862],{"type":418,"value":863}," sqlServer",{"type":413,"tag":501,"props":865,"children":866},{"style":519},[867],{"type":418,"value":522},{"type":413,"tag":501,"props":869,"children":870},{"style":519},[871],{"type":418,"value":527},{"type":413,"tag":501,"props":873,"children":874},{"style":508},[875],{"type":418,"value":876}," Server",{"type":413,"tag":501,"props":878,"children":879},{"style":519},[880],{"type":418,"value":575},{"type":413,"tag":501,"props":882,"children":883},{"style":519},[884],{"type":418,"value":885},"$\"",{"type":413,"tag":501,"props":887,"children":888},{"style":583},[889],{"type":418,"value":890},"sql-sqlDbWithAzureAd-",{"type":413,"tag":501,"props":892,"children":893},{"style":519},[894],{"type":418,"value":895},"{",{"type":413,"tag":501,"props":897,"children":898},{"style":557},[899],{"type":418,"value":900},"Deployment",{"type":413,"tag":501,"props":902,"children":903},{"style":519},[904],{"type":418,"value":564},{"type":413,"tag":501,"props":906,"children":907},{"style":557},[908],{"type":418,"value":909},"Instance",{"type":413,"tag":501,"props":911,"children":912},{"style":519},[913],{"type":418,"value":564},{"type":413,"tag":501,"props":915,"children":916},{"style":557},[917],{"type":418,"value":918},"StackName",{"type":413,"tag":501,"props":920,"children":921},{"style":519},[922],{"type":418,"value":923},"}\"",{"type":413,"tag":501,"props":925,"children":926},{"style":519},[927],{"type":418,"value":704},{"type":413,"tag":501,"props":929,"children":930},{"style":519},[931],{"type":418,"value":527},{"type":413,"tag":501,"props":933,"children":934},{"style":508},[935],{"type":418,"value":936}," ServerArgs\n",{"type":413,"tag":501,"props":938,"children":939},{"class":503,"line":540},[940],{"type":413,"tag":501,"props":941,"children":942},{"style":519},[943],{"type":418,"value":722},{"type":413,"tag":501,"props":945,"children":946},{"class":503,"line":598},[947,952,956,961,965,970],{"type":413,"tag":501,"props":948,"children":949},{"style":557},[950],{"type":418,"value":951},"    ResourceGroupName ",{"type":413,"tag":501,"props":953,"children":954},{"style":519},[955],{"type":418,"value":736},{"type":413,"tag":501,"props":957,"children":958},{"style":557},[959],{"type":418,"value":960}," resourceGroup",{"type":413,"tag":501,"props":962,"children":963},{"style":519},[964],{"type":418,"value":564},{"type":413,"tag":501,"props":966,"children":967},{"style":557},[968],{"type":418,"value":969},"Name",{"type":413,"tag":501,"props":971,"children":972},{"style":519},[973],{"type":418,"value":745},{"type":413,"tag":501,"props":975,"children":976},{"class":503,"line":649},[977,982,986,990],{"type":413,"tag":501,"props":978,"children":979},{"style":557},[980],{"type":418,"value":981},"    Administrators ",{"type":413,"tag":501,"props":983,"children":984},{"style":519},[985],{"type":418,"value":736},{"type":413,"tag":501,"props":987,"children":988},{"style":519},[989],{"type":418,"value":527},{"type":413,"tag":501,"props":991,"children":992},{"style":508},[993],{"type":418,"value":994}," ServerExternalAdministratorArgs\n",{"type":413,"tag":501,"props":996,"children":997},{"class":503,"line":659},[998],{"type":413,"tag":501,"props":999,"children":1000},{"style":519},[1001],{"type":418,"value":1002},"    {\n",{"type":413,"tag":501,"props":1004,"children":1005},{"class":503,"line":716},[1006,1011,1015,1019,1023,1028],{"type":413,"tag":501,"props":1007,"children":1008},{"style":557},[1009],{"type":418,"value":1010},"        Login ",{"type":413,"tag":501,"props":1012,"children":1013},{"style":519},[1014],{"type":418,"value":736},{"type":413,"tag":501,"props":1016,"children":1017},{"style":557},[1018],{"type":418,"value":669},{"type":413,"tag":501,"props":1020,"children":1021},{"style":519},[1022],{"type":418,"value":564},{"type":413,"tag":501,"props":1024,"children":1025},{"style":557},[1026],{"type":418,"value":1027},"UserPrincipalName",{"type":413,"tag":501,"props":1029,"children":1030},{"style":519},[1031],{"type":418,"value":745},{"type":413,"tag":501,"props":1033,"children":1034},{"class":503,"line":725},[1035,1040,1044,1048,1052,1057],{"type":413,"tag":501,"props":1036,"children":1037},{"style":557},[1038],{"type":418,"value":1039},"        Sid ",{"type":413,"tag":501,"props":1041,"children":1042},{"style":519},[1043],{"type":418,"value":736},{"type":413,"tag":501,"props":1045,"children":1046},{"style":557},[1047],{"type":418,"value":669},{"type":413,"tag":501,"props":1049,"children":1050},{"style":519},[1051],{"type":418,"value":564},{"type":413,"tag":501,"props":1053,"children":1054},{"style":557},[1055],{"type":418,"value":1056},"Id",{"type":413,"tag":501,"props":1058,"children":1059},{"style":519},[1060],{"type":418,"value":745},{"type":413,"tag":501,"props":1062,"children":1063},{"class":503,"line":748},[1064,1069,1073,1079],{"type":413,"tag":501,"props":1065,"children":1066},{"style":557},[1067],{"type":418,"value":1068},"        AzureADOnlyAuthentication ",{"type":413,"tag":501,"props":1070,"children":1071},{"style":519},[1072],{"type":418,"value":736},{"type":413,"tag":501,"props":1074,"children":1076},{"style":1075},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[1077],{"type":418,"value":1078}," true",{"type":413,"tag":501,"props":1080,"children":1081},{"style":519},[1082],{"type":418,"value":745},{"type":413,"tag":501,"props":1084,"children":1085},{"class":503,"line":769},[1086,1091,1095,1100,1104,1109],{"type":413,"tag":501,"props":1087,"children":1088},{"style":557},[1089],{"type":418,"value":1090},"        AdministratorType ",{"type":413,"tag":501,"props":1092,"children":1093},{"style":519},[1094],{"type":418,"value":736},{"type":413,"tag":501,"props":1096,"children":1097},{"style":557},[1098],{"type":418,"value":1099}," AdministratorType",{"type":413,"tag":501,"props":1101,"children":1102},{"style":519},[1103],{"type":418,"value":564},{"type":413,"tag":501,"props":1105,"children":1106},{"style":557},[1107],{"type":418,"value":1108},"ActiveDirectory",{"type":413,"tag":501,"props":1110,"children":1111},{"style":519},[1112],{"type":418,"value":745},{"type":413,"tag":501,"props":1114,"children":1115},{"class":503,"line":797},[1116,1121,1125,1130,1134,1139],{"type":413,"tag":501,"props":1117,"children":1118},{"style":557},[1119],{"type":418,"value":1120},"        PrincipalType ",{"type":413,"tag":501,"props":1122,"children":1123},{"style":519},[1124],{"type":418,"value":736},{"type":413,"tag":501,"props":1126,"children":1127},{"style":557},[1128],{"type":418,"value":1129}," PrincipalType",{"type":413,"tag":501,"props":1131,"children":1132},{"style":519},[1133],{"type":418,"value":564},{"type":413,"tag":501,"props":1135,"children":1136},{"style":557},[1137],{"type":418,"value":1138},"User",{"type":413,"tag":501,"props":1140,"children":1141},{"style":519},[1142],{"type":418,"value":745},{"type":413,"tag":501,"props":1144,"children":1146},{"class":503,"line":1145},11,[1147],{"type":413,"tag":501,"props":1148,"children":1149},{"style":519},[1150],{"type":418,"value":1151},"    },\n",{"type":413,"tag":501,"props":1153,"children":1155},{"class":503,"line":1154},12,[1156],{"type":413,"tag":501,"props":1157,"children":1158},{"style":519},[1159],{"type":418,"value":803},{"type":413,"tag":414,"props":1161,"children":1162},{},[1163,1165,1170],{"type":418,"value":1164},"Nothing special here: we are using the variable ",{"type":413,"tag":443,"props":1166,"children":1168},{"className":1167},[],[1169],{"type":418,"value":695},{"type":418,"value":1171}," that is our newly created user to set the administrator of the SQL Server and we set the authentication to Azure AD only. We can then create the database:",{"type":413,"tag":492,"props":1173,"children":1175},{"className":494,"code":1174,"language":326,"meta":401,"style":401},"var database = new Database(\"sqldb-sqlDbWithAzureAd-Main\", new DatabaseArgs\n{\n    ResourceGroupName = resourceGroup.Name,\n    ServerName = sqlServer.Name,\n    Sku = new SkuArgs\n    {\n        Name = \"Basic\"\n    }\n});\n",[1176],{"type":413,"tag":443,"props":1177,"children":1178},{"__ignoreMap":401},[1179,1234,1241,1268,1296,1317,1324,1349,1357],{"type":413,"tag":501,"props":1180,"children":1181},{"class":503,"line":504},[1182,1186,1191,1195,1199,1204,1208,1212,1217,1221,1225,1229],{"type":413,"tag":501,"props":1183,"children":1184},{"style":508},[1185],{"type":418,"value":511},{"type":413,"tag":501,"props":1187,"children":1188},{"style":508},[1189],{"type":418,"value":1190}," database",{"type":413,"tag":501,"props":1192,"children":1193},{"style":519},[1194],{"type":418,"value":522},{"type":413,"tag":501,"props":1196,"children":1197},{"style":519},[1198],{"type":418,"value":527},{"type":413,"tag":501,"props":1200,"children":1201},{"style":508},[1202],{"type":418,"value":1203}," Database",{"type":413,"tag":501,"props":1205,"children":1206},{"style":519},[1207],{"type":418,"value":575},{"type":413,"tag":501,"props":1209,"children":1210},{"style":519},[1211],{"type":418,"value":580},{"type":413,"tag":501,"props":1213,"children":1214},{"style":583},[1215],{"type":418,"value":1216},"sqldb-sqlDbWithAzureAd-Main",{"type":413,"tag":501,"props":1218,"children":1219},{"style":519},[1220],{"type":418,"value":580},{"type":413,"tag":501,"props":1222,"children":1223},{"style":519},[1224],{"type":418,"value":704},{"type":413,"tag":501,"props":1226,"children":1227},{"style":519},[1228],{"type":418,"value":527},{"type":413,"tag":501,"props":1230,"children":1231},{"style":508},[1232],{"type":418,"value":1233}," DatabaseArgs\n",{"type":413,"tag":501,"props":1235,"children":1236},{"class":503,"line":540},[1237],{"type":413,"tag":501,"props":1238,"children":1239},{"style":519},[1240],{"type":418,"value":722},{"type":413,"tag":501,"props":1242,"children":1243},{"class":503,"line":598},[1244,1248,1252,1256,1260,1264],{"type":413,"tag":501,"props":1245,"children":1246},{"style":557},[1247],{"type":418,"value":951},{"type":413,"tag":501,"props":1249,"children":1250},{"style":519},[1251],{"type":418,"value":736},{"type":413,"tag":501,"props":1253,"children":1254},{"style":557},[1255],{"type":418,"value":960},{"type":413,"tag":501,"props":1257,"children":1258},{"style":519},[1259],{"type":418,"value":564},{"type":413,"tag":501,"props":1261,"children":1262},{"style":557},[1263],{"type":418,"value":969},{"type":413,"tag":501,"props":1265,"children":1266},{"style":519},[1267],{"type":418,"value":745},{"type":413,"tag":501,"props":1269,"children":1270},{"class":503,"line":649},[1271,1276,1280,1284,1288,1292],{"type":413,"tag":501,"props":1272,"children":1273},{"style":557},[1274],{"type":418,"value":1275},"    ServerName ",{"type":413,"tag":501,"props":1277,"children":1278},{"style":519},[1279],{"type":418,"value":736},{"type":413,"tag":501,"props":1281,"children":1282},{"style":557},[1283],{"type":418,"value":863},{"type":413,"tag":501,"props":1285,"children":1286},{"style":519},[1287],{"type":418,"value":564},{"type":413,"tag":501,"props":1289,"children":1290},{"style":557},[1291],{"type":418,"value":969},{"type":413,"tag":501,"props":1293,"children":1294},{"style":519},[1295],{"type":418,"value":745},{"type":413,"tag":501,"props":1297,"children":1298},{"class":503,"line":659},[1299,1304,1308,1312],{"type":413,"tag":501,"props":1300,"children":1301},{"style":557},[1302],{"type":418,"value":1303},"    Sku ",{"type":413,"tag":501,"props":1305,"children":1306},{"style":519},[1307],{"type":418,"value":736},{"type":413,"tag":501,"props":1309,"children":1310},{"style":519},[1311],{"type":418,"value":527},{"type":413,"tag":501,"props":1313,"children":1314},{"style":508},[1315],{"type":418,"value":1316}," SkuArgs\n",{"type":413,"tag":501,"props":1318,"children":1319},{"class":503,"line":716},[1320],{"type":413,"tag":501,"props":1321,"children":1322},{"style":519},[1323],{"type":418,"value":1002},{"type":413,"tag":501,"props":1325,"children":1326},{"class":503,"line":725},[1327,1332,1336,1340,1345],{"type":413,"tag":501,"props":1328,"children":1329},{"style":557},[1330],{"type":418,"value":1331},"        Name ",{"type":413,"tag":501,"props":1333,"children":1334},{"style":519},[1335],{"type":418,"value":736},{"type":413,"tag":501,"props":1337,"children":1338},{"style":519},[1339],{"type":418,"value":784},{"type":413,"tag":501,"props":1341,"children":1342},{"style":583},[1343],{"type":418,"value":1344},"Basic",{"type":413,"tag":501,"props":1346,"children":1347},{"style":519},[1348],{"type":418,"value":794},{"type":413,"tag":501,"props":1350,"children":1351},{"class":503,"line":748},[1352],{"type":413,"tag":501,"props":1353,"children":1354},{"style":519},[1355],{"type":418,"value":1356},"    }\n",{"type":413,"tag":501,"props":1358,"children":1359},{"class":503,"line":769},[1360],{"type":413,"tag":501,"props":1361,"children":1362},{"style":519},[1363],{"type":418,"value":803},{"type":413,"tag":420,"props":1365,"children":1367},{"id":1366},"grant-sql-database-access-permissions-to-azure-ad-entities",[1368],{"type":418,"value":1369},"Grant SQL Database access permissions to Azure AD entities",{"type":413,"tag":414,"props":1371,"children":1372},{},[1373],{"type":418,"value":1374},"Once we have provisioned the Azure SQL Server and its database, here comes the tough part: we need to configure who can access the database. In a project, you will probably have to give access to some users and to the Azure resources that need to query the database (you will have to assign these resources a managed identity before that). But to keep things simple, we will just consider we need to grant SQL Database access to an Azure AD group. That could be a good way to do things by the way: create an Azure AD group, grant permissions to this group and add users and managed identities that need access to the database.",{"type":413,"tag":414,"props":1376,"children":1377},{},[1378,1380,1387],{"type":418,"value":1379},"Why did I say that this part was tough? It's because to grant SQL database permissions, we need to execute an SQL command on the Server as you can read ",{"type":413,"tag":432,"props":1381,"children":1384},{"href":1382,"rel":1383},"https://docs.microsoft.com/en-us/azure/app-service/tutorial-connect-msi-sql-database?tabs=windowsclient%2Cef%2Cdotnet#grant-permissions-to-managed-identity",[436],[1385],{"type":418,"value":1386},"in the documentation",{"type":418,"value":564},{"type":413,"tag":492,"props":1389,"children":1393},{"className":1390,"code":1391,"language":1392,"meta":401,"style":401},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","CREATE USER [\u003Cidentity-name>] FROM EXTERNAL PROVIDER;\nALTER ROLE db_datareader ADD MEMBER [\u003Cidentity-name>];\nALTER ROLE db_datawriter ADD MEMBER [\u003Cidentity-name>];\nGO\n","sql",[1394],{"type":413,"tag":443,"props":1395,"children":1396},{"__ignoreMap":401},[1397,1431,1459,1483],{"type":413,"tag":501,"props":1398,"children":1399},{"class":503,"line":504},[1400,1406,1411,1416,1421,1426],{"type":413,"tag":501,"props":1401,"children":1403},{"style":1402},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[1404],{"type":418,"value":1405},"CREATE",{"type":413,"tag":501,"props":1407,"children":1408},{"style":557},[1409],{"type":418,"value":1410}," USER [\u003Cidentity-name>] ",{"type":413,"tag":501,"props":1412,"children":1413},{"style":1402},[1414],{"type":418,"value":1415},"FROM",{"type":413,"tag":501,"props":1417,"children":1418},{"style":1402},[1419],{"type":418,"value":1420}," EXTERNAL",{"type":413,"tag":501,"props":1422,"children":1423},{"style":1402},[1424],{"type":418,"value":1425}," PROVIDER",{"type":413,"tag":501,"props":1427,"children":1428},{"style":557},[1429],{"type":418,"value":1430},";\n",{"type":413,"tag":501,"props":1432,"children":1433},{"class":503,"line":540},[1434,1439,1444,1449,1454],{"type":413,"tag":501,"props":1435,"children":1436},{"style":1402},[1437],{"type":418,"value":1438},"ALTER",{"type":413,"tag":501,"props":1440,"children":1441},{"style":1402},[1442],{"type":418,"value":1443}," ROLE",{"type":413,"tag":501,"props":1445,"children":1446},{"style":557},[1447],{"type":418,"value":1448}," db_datareader ",{"type":413,"tag":501,"props":1450,"children":1451},{"style":1402},[1452],{"type":418,"value":1453},"ADD",{"type":413,"tag":501,"props":1455,"children":1456},{"style":557},[1457],{"type":418,"value":1458}," MEMBER [\u003Cidentity-name>];\n",{"type":413,"tag":501,"props":1460,"children":1461},{"class":503,"line":598},[1462,1466,1470,1475,1479],{"type":413,"tag":501,"props":1463,"children":1464},{"style":1402},[1465],{"type":418,"value":1438},{"type":413,"tag":501,"props":1467,"children":1468},{"style":1402},[1469],{"type":418,"value":1443},{"type":413,"tag":501,"props":1471,"children":1472},{"style":557},[1473],{"type":418,"value":1474}," db_datawriter ",{"type":413,"tag":501,"props":1476,"children":1477},{"style":1402},[1478],{"type":418,"value":1453},{"type":413,"tag":501,"props":1480,"children":1481},{"style":557},[1482],{"type":418,"value":1458},{"type":413,"tag":501,"props":1484,"children":1485},{"class":503,"line":649},[1486],{"type":413,"tag":501,"props":1487,"children":1488},{"style":1402},[1489],{"type":418,"value":1490},"GO\n",{"type":413,"tag":414,"props":1492,"children":1493},{},[1494,1496,1502,1504,1510],{"type":418,"value":1495},"With this command, we are creating a user and giving ",{"type":413,"tag":443,"props":1497,"children":1499},{"className":1498},[],[1500],{"type":418,"value":1501},"db_datareader",{"type":418,"value":1503}," and ",{"type":413,"tag":443,"props":1505,"children":1507},{"className":1506},[],[1508],{"type":418,"value":1509},"db_datawriter",{"type":418,"value":1511}," roles. However it is not a classical user, it's a user that is \"external\" to the database: in our case, it corresponds to an Azure AD entity (a user, group, or application).",{"type":413,"tag":414,"props":1513,"children":1514},{},[1515],{"type":418,"value":1516},"So it's not just about setting a property to properly configure an Azure resource, it's a bit more complicated.",{"type":413,"tag":414,"props":1518,"children":1519},{},[1520],{"type":418,"value":1521},"I see multiple ways of doing that:",{"type":413,"tag":1523,"props":1524,"children":1525},"ul",{},[1526,1532,1537],{"type":413,"tag":1527,"props":1528,"children":1529},"li",{},[1530],{"type":418,"value":1531},"Create a new Pulumi provider \"SQL Server provider\" that is to able manage users in an SQL Server database",{"type":413,"tag":1527,"props":1533,"children":1534},{},[1535],{"type":418,"value":1536},"Write custom C# code that executes the SQL command once the database is created",{"type":413,"tag":1527,"props":1538,"children":1539},{},[1540,1542,1548],{"type":418,"value":1541},"Use the Pulumi Command provider to execute the SQL command using the ",{"type":413,"tag":443,"props":1543,"children":1545},{"className":1544},[],[1546],{"type":418,"value":1547},"sqlcmd",{"type":418,"value":1549}," utility",{"type":413,"tag":414,"props":1551,"children":1552},{},[1553],{"type":418,"value":1554},"Let's review these solutions.",{"type":413,"tag":1556,"props":1557,"children":1559},"h3",{"id":1558},"new-sql-server-provider",[1560],{"type":418,"value":1561},"New \"SQL Server Provider\"",{"type":413,"tag":414,"props":1563,"children":1564},{},[1565,1567,1574],{"type":418,"value":1566},"To manage SQL Server resources like users and roles, we can create a complete provider. We could create it from scratch of course or use this ",{"type":413,"tag":432,"props":1568,"children":1571},{"href":1569,"rel":1570},"https://github.com/pulumi/pulumi-provider-boilerplate",[436],[1572],{"type":418,"value":1573},"Pulumi GitHub repository",{"type":418,"value":1575}," that provides some boilerplate code to create a Pulumi provider. Usually, Pulumi providers are written in Go (like the Terraform providers by the way) and generate SDKs for all programming languages supported by Pulumi.",{"type":413,"tag":414,"props":1577,"children":1578},{},[1579],{"type":413,"tag":1580,"props":1581,"children":1587},"img",{"alt":1582,"className":1583,"src":1586},"xyz Pulumi Provider boilerplate code repository on GitHub.",[1584,1585],"rounded-lg","mx-auto","/posts/images/sqldatabase_ad_provider_1.png",[],{"type":413,"tag":414,"props":1589,"children":1590},{},[1591,1593,1600,1602,1609,1611,1618],{"type":418,"value":1592},"Another way would be to adapt the existing ",{"type":413,"tag":432,"props":1594,"children":1597},{"href":1595,"rel":1596},"https://registry.terraform.io/providers/betr-io/mssql/latest/docs",[436],[1598],{"type":418,"value":1599},"Microsoft SQL Server Provider",{"type":418,"value":1601}," for Terraform. This Terraform provider made by the community enables you to create and manage logins and users on a SQL Server. I talked about \"adapting\" this provider because you can create a Pulumi provider out of a Terraform provider by using the ",{"type":413,"tag":432,"props":1603,"children":1606},{"href":1604,"rel":1605},"https://github.com/pulumi/pulumi-terraform-bridge",[436],[1607],{"type":418,"value":1608},"Pulumi Terraform Bridge",{"type":418,"value":1610},". That's great because instead of reinventing the wheel you can benefit from Terraform ecosystem by creating a Pulumi provider that wraps an existing Terraform provider. This ",{"type":413,"tag":432,"props":1612,"children":1615},{"href":1613,"rel":1614},"https://github.com/pulumi/pulumi-tf-provider-boilerplate",[436],[1616],{"type":418,"value":1617},"GitHub repository",{"type":418,"value":1619}," contains boilerplate code to do exactly that.",{"type":413,"tag":414,"props":1621,"children":1622},{},[1623],{"type":413,"tag":1580,"props":1624,"children":1628},{"alt":1625,"className":1626,"src":1627},"Pulumi Terraform Bridge repository on GitHub.",[1584,1585],"/posts/images/sqldatabase_ad_provider_2.png",[],{"type":413,"tag":466,"props":1630,"children":1631},{"icon":468},[1632],{"type":413,"tag":414,"props":1633,"children":1634},{},[1635,1637,1643],{"type":418,"value":1636},"You might have noticed that I sometimes criticize Terraform in my articles. That's not because I think Terraform is a bad infrastructure as code solution, in fact, I think it is a great solution with a rich ecosystem. However, I am critical of Terraform because I believe Infrastructure as Code should be done with programming languages instead of Domain-Specific Languages. Moreover, there are some areas (API coverage of major cloud providers, security, IDE support, ...) where I found Terraform is not good enough, especially compared to other platforms like Pulumi. So I am always a bit disappointed when I see that many people choose by default Terraform as their infrastructure as code platform without considering alternatives (and I am not only talking about Pulumi, there are also Farmer and Bicep for instance), even when these alternatives would be better suited to their use cases. That being said, Terraform has also advantages like its great community that creates and contributes to many providers like the ",{"type":413,"tag":443,"props":1638,"children":1640},{"className":1639},[],[1641],{"type":418,"value":1642},"mssql",{"type":418,"value":1644}," one.",{"type":413,"tag":414,"props":1646,"children":1647},{},[1648,1650,1655],{"type":418,"value":1649},"This first solution of creating a new \"SQL Server Provider\" (whether it be from scratch, from boilerplate code, or from the ",{"type":413,"tag":443,"props":1651,"children":1653},{"className":1652},[],[1654],{"type":418,"value":1642},{"type":418,"value":1656}," Terraform provider) is interesting but could be time-consuming because there are some things to set up and some amount of code to write.",{"type":413,"tag":1556,"props":1658,"children":1660},{"id":1659},"custom-c-code",[1661],{"type":418,"value":1662},"Custom C# code",{"type":413,"tag":414,"props":1664,"children":1665},{},[1666,1668,1680,1682,1689],{"type":418,"value":1667},"When you need to do something specific and there is no existing provider that can help you with it, you can just write the code to do it yourself without creating a complete provider. It's one of the reasons why I like Pulumi, even if you are doing Infrastructure as Code, at the end of the day you are just developing software so you can code what you need in the language you are familiar with. For instance, as I am developing in .NET, I can use the ",{"type":413,"tag":432,"props":1669,"children":1672},{"href":1670,"rel":1671},"https://docs.microsoft.com/en-us/sql/connect/ado-net/overview-sqlclient-driver",[436],[1673,1678],{"type":413,"tag":443,"props":1674,"children":1676},{"className":1675},[],[1677],{"type":418,"value":448},{"type":418,"value":1679}," library",{"type":418,"value":1681}," (which is a data provider for Azure SQL Database) to connect and send commands to the database. And if I want to use ",{"type":413,"tag":432,"props":1683,"children":1686},{"href":1684,"rel":1685},"https://github.com/DapperLib/Dapper",[436],[1687],{"type":418,"value":1688},"Dapper",{"type":418,"value":1690}," on top of it because that's the library I am used to for querying a database I can. Hence writing the code that executes on the database the SQL command we have previously seen should not be very difficult.",{"type":413,"tag":414,"props":1692,"children":1693},{},[1694],{"type":418,"value":1695},"Now, even if we are using imperative language in Pulumi to write the infrastructure code it's still declarative infrastructure as code with a state. Therefore, we have to be careful about how and when this custom code should be executed.",{"type":413,"tag":414,"props":1697,"children":1698},{},[1699,1701,1707],{"type":418,"value":1700},"The easiest way is to use an ",{"type":413,"tag":443,"props":1702,"children":1704},{"className":1703},[],[1705],{"type":418,"value":1706},"Apply",{"type":418,"value":1708}," method on an output of the database like this:",{"type":413,"tag":492,"props":1710,"children":1712},{"className":494,"code":1711,"language":326,"meta":401,"style":401},"database.Name.Apply(name =>\n{\n    /*** \n     * Indempotent code using Microsoft.Data.SqlClient library\n     * to execute the SQL command that assigns the correct roles\n     * to the Azure AD group we want to have access to the database.\n    ***/ \n    return true;\n});\n",[1713],{"type":413,"tag":443,"props":1714,"children":1715},{"__ignoreMap":401},[1716,1754,1761,1770,1778,1786,1794,1807,1824],{"type":413,"tag":501,"props":1717,"children":1718},{"class":503,"line":504},[1719,1724,1728,1732,1736,1740,1744,1749],{"type":413,"tag":501,"props":1720,"children":1721},{"style":557},[1722],{"type":418,"value":1723},"database",{"type":413,"tag":501,"props":1725,"children":1726},{"style":519},[1727],{"type":418,"value":564},{"type":413,"tag":501,"props":1729,"children":1730},{"style":557},[1731],{"type":418,"value":969},{"type":413,"tag":501,"props":1733,"children":1734},{"style":519},[1735],{"type":418,"value":564},{"type":413,"tag":501,"props":1737,"children":1738},{"style":567},[1739],{"type":418,"value":1706},{"type":413,"tag":501,"props":1741,"children":1742},{"style":519},[1743],{"type":418,"value":575},{"type":413,"tag":501,"props":1745,"children":1746},{"style":508},[1747],{"type":418,"value":1748},"name",{"type":413,"tag":501,"props":1750,"children":1751},{"style":519},[1752],{"type":418,"value":1753}," =>\n",{"type":413,"tag":501,"props":1755,"children":1756},{"class":503,"line":540},[1757],{"type":413,"tag":501,"props":1758,"children":1759},{"style":519},[1760],{"type":418,"value":722},{"type":413,"tag":501,"props":1762,"children":1763},{"class":503,"line":598},[1764],{"type":413,"tag":501,"props":1765,"children":1767},{"style":1766},"--shiki-light:#90A4AE;--shiki-default:#546E7A;--shiki-dark:#676E95;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[1768],{"type":418,"value":1769},"    /*** \n",{"type":413,"tag":501,"props":1771,"children":1772},{"class":503,"line":649},[1773],{"type":413,"tag":501,"props":1774,"children":1775},{"style":1766},[1776],{"type":418,"value":1777},"     * Indempotent code using Microsoft.Data.SqlClient library\n",{"type":413,"tag":501,"props":1779,"children":1780},{"class":503,"line":659},[1781],{"type":413,"tag":501,"props":1782,"children":1783},{"style":1766},[1784],{"type":418,"value":1785},"     * to execute the SQL command that assigns the correct roles\n",{"type":413,"tag":501,"props":1787,"children":1788},{"class":503,"line":716},[1789],{"type":413,"tag":501,"props":1790,"children":1791},{"style":1766},[1792],{"type":418,"value":1793},"     * to the Azure AD group we want to have access to the database.\n",{"type":413,"tag":501,"props":1795,"children":1796},{"class":503,"line":725},[1797,1802],{"type":413,"tag":501,"props":1798,"children":1799},{"style":1766},[1800],{"type":418,"value":1801},"    ***/",{"type":413,"tag":501,"props":1803,"children":1804},{"style":557},[1805],{"type":418,"value":1806}," \n",{"type":413,"tag":501,"props":1808,"children":1809},{"class":503,"line":748},[1810,1816,1820],{"type":413,"tag":501,"props":1811,"children":1813},{"style":1812},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[1814],{"type":418,"value":1815},"    return",{"type":413,"tag":501,"props":1817,"children":1818},{"style":1075},[1819],{"type":418,"value":1078},{"type":413,"tag":501,"props":1821,"children":1822},{"style":519},[1823],{"type":418,"value":1430},{"type":413,"tag":501,"props":1825,"children":1826},{"class":503,"line":769},[1827],{"type":413,"tag":501,"props":1828,"children":1829},{"style":519},[1830],{"type":418,"value":803},{"type":413,"tag":414,"props":1832,"children":1833},{},[1834,1836,1841],{"type":418,"value":1835},"The code in the ",{"type":413,"tag":443,"props":1837,"children":1839},{"className":1838},[],[1840],{"type":418,"value":1706},{"type":418,"value":1842}," will execute on every run after the resource is created, that is why it needs to be idempotent. Having to make the code idempotent is a constraint that I would prefer to avoid but at least it gives us a simple way to execute the code that grants access to the database.",{"type":413,"tag":414,"props":1844,"children":1845},{},[1846,1848,1855,1857,1864,1866,1873],{"type":418,"value":1847},"Another way would be to use ",{"type":413,"tag":432,"props":1849,"children":1852},{"href":1850,"rel":1851},"https://www.pulumi.com/docs/intro/concepts/resources/dynamic-providers/",[436],[1853],{"type":418,"value":1854},"Dynamic Providers",{"type":418,"value":1856}," whose purpose is exactly that: do an infrastructure task that no existing provider can help you deliver. You can see some use cases of dynamic providers in ",{"type":413,"tag":432,"props":1858,"children":1861},{"href":1859,"rel":1860},"https://www.pulumi.com/blog/dynamic-providers/#sample-use-cases",[436],[1862],{"type":418,"value":1863},"this Pulumi article",{"type":418,"value":1865},". In our use case, we could imagine writing a dynamic resource provider for an Azure AD entity user in an Azure SQL Database.  We would have to implement the different CRUD operations to handle the different use cases properly (a user is added, a user is removed, user roles are updated, ...). Unfortunately, as you can see in ",{"type":413,"tag":432,"props":1867,"children":1870},{"href":1868,"rel":1869},"https://github.com/pulumi/pulumi/issues/3638",[436],[1871],{"type":418,"value":1872},"this GitHub issue",{"type":418,"value":1874},", .NET Dynamic Providers are not yet supported (only TypesScript, JavaScript and Python are for the moment). It's a shame because Dynamic Providers provide an easy and efficient way of supporting custom resource types.",{"type":413,"tag":1556,"props":1876,"children":1878},{"id":1877},"command-provider-with-the-sqlcmd-utility",[1879,1881,1886],{"type":418,"value":1880},"Command provider with the ",{"type":413,"tag":443,"props":1882,"children":1884},{"className":1883},[],[1885],{"type":418,"value":1547},{"type":418,"value":1549},{"type":413,"tag":414,"props":1888,"children":1889},{},[1890,1896,1898,1909,1911,1916,1918,1925],{"type":413,"tag":432,"props":1891,"children":1893},{"href":1382,"rel":1892},[436],[1894],{"type":418,"value":1895},"The Microsoft tutorial",{"type":418,"value":1897},", that shows how to grant database permissions to an Azure AD entity, explains how the necessary SQL commands can be run using the ",{"type":413,"tag":432,"props":1899,"children":1902},{"href":1900,"rel":1901},"https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility",[436],[1903,1908],{"type":413,"tag":443,"props":1904,"children":1906},{"className":1905},[],[1907],{"type":418,"value":1547},{"type":418,"value":1549},{"type":418,"value":1910},". So instead of writing some C# code to do the same, an interesting idea would be to directly run the ",{"type":413,"tag":443,"props":1912,"children":1914},{"className":1913},[],[1915],{"type":418,"value":1547},{"type":418,"value":1917}," utility. And you know what? There is a Pulumi provider for executing commands and scripts: ",{"type":413,"tag":432,"props":1919,"children":1922},{"href":1920,"rel":1921},"https://www.pulumi.com/registry/packages/command/api-docs/",[436],[1923],{"type":418,"value":1924},"the Command Provider",{"type":418,"value":564},{"type":413,"tag":414,"props":1927,"children":1928},{},[1929],{"type":413,"tag":1580,"props":1930,"children":1934},{"alt":1931,"className":1932,"src":1933},"Pulumi Command Provider on GitHub.",[1584,1585],"/posts/images/sqldatabase_ad_pulumi_1.png",[],{"type":413,"tag":414,"props":1936,"children":1937},{},[1938,1940,1945,1947,1953,1955,1960],{"type":418,"value":1939},"Because it's a Pulumi provider, the ",{"type":413,"tag":443,"props":1941,"children":1943},{"className":1942},[],[1944],{"type":418,"value":1547},{"type":418,"value":1946}," command would be executed \"as part of the Pulumi resource model\" which means the scripts would be executed at the corresponding time of the resource life-cycle (the ",{"type":413,"tag":443,"props":1948,"children":1950},{"className":1949},[],[1951],{"type":418,"value":1952},"create",{"type":418,"value":1954}," script when the resource is created and so on). So it's very nice and not the same as executing the ",{"type":413,"tag":443,"props":1956,"children":1958},{"className":1957},[],[1959],{"type":418,"value":1547},{"type":418,"value":1961}," outside of a Pulumi program, without access to all the variables and where you would have to make your script idempotent. Moreover, the ability to execute commands remotely can bring interesting use cases, just not for our current concern here.",{"type":413,"tag":466,"props":1963,"children":1965},{"icon":1964},"i-heroicons-light-bulb",[1966],{"type":413,"tag":414,"props":1967,"children":1968},{},[1969,1971,1976,1977,1983,1985,1991,1993,1999,2000,2006,2008,2015],{"type":418,"value":1970},"Pulumi Command Provider is currently in preview and only supports running scripts on ",{"type":413,"tag":443,"props":1972,"children":1974},{"className":1973},[],[1975],{"type":418,"value":1952},{"type":418,"value":1503},{"type":413,"tag":443,"props":1978,"children":1980},{"className":1979},[],[1981],{"type":418,"value":1982},"destroy",{"type":418,"value":1984}," operations (support for ",{"type":413,"tag":443,"props":1986,"children":1988},{"className":1987},[],[1989],{"type":418,"value":1990},"diff",{"type":418,"value":1992},", ",{"type":413,"tag":443,"props":1994,"children":1996},{"className":1995},[],[1997],{"type":418,"value":1998},"update",{"type":418,"value":1503},{"type":413,"tag":443,"props":2001,"children":2003},{"className":2002},[],[2004],{"type":418,"value":2005},"read",{"type":418,"value":2007}," operations ",{"type":413,"tag":432,"props":2009,"children":2012},{"href":2010,"rel":2011},"https://github.com/pulumi/pulumi-command/issues/20",[436],[2013],{"type":418,"value":2014},"will probably be added later",{"type":418,"value":2016},"). It works fine but does not log details about the error when a script fails, which makes debugging difficult. That should not prevent you from using it but as with any components in preview, use it with caution knowing everything is not perfect yet.",{"type":413,"tag":420,"props":2018,"children":2020},{"id":2019},"implement-the-database-permissions-for-an-azure-ad-group",[2021],{"type":418,"value":2022},"Implement the database permissions for an Azure AD Group",{"type":413,"tag":414,"props":2024,"children":2025},{},[2026,2028,2033,2035,2040],{"type":418,"value":2027},"Of the 3 possible solutions let's take the 3rd one with the Command provider and the ",{"type":413,"tag":443,"props":2029,"children":2031},{"className":2030},[],[2032],{"type":418,"value":1547},{"type":418,"value":2034}," utility. It is probably not the \"best\" solution but I thought it would be simpler to use the ",{"type":413,"tag":443,"props":2036,"children":2038},{"className":2037},[],[2039],{"type":418,"value":1547},{"type":418,"value":2041}," utility than writing a complete provider or even custom C# code to do the same. Furthermore, it's the opportunity to test the Command provider which is fairly new.",{"type":413,"tag":1556,"props":2043,"children":2045},{"id":2044},"allow-the-machine-running-the-pulumi-program-to-connect-to-the-sql-server",[2046],{"type":418,"value":2047},"Allow the machine running the Pulumi program to connect to the SQL Server",{"type":413,"tag":414,"props":2049,"children":2050},{},[2051,2053,2059],{"type":418,"value":2052},"To run a SQL command in the database, the machine that executes the Pulumi program needs to have its public IP authorized. To programmatically retrieve the public IP address from where the Pulumi program is running we can use ",{"type":413,"tag":443,"props":2054,"children":2056},{"className":2055},[],[2057],{"type":418,"value":2058},"ipify API",{"type":418,"value":2060},". It's a simple open source HTTP API that returns the public IP address of the caller.",{"type":413,"tag":492,"props":2062,"children":2064},{"className":494,"code":2063,"language":326,"meta":401,"style":401},"var publicIp = Output.Create(new HttpClient().GetStringAsync(\"https://api.ipify.org\"));\n",[2065],{"type":413,"tag":443,"props":2066,"children":2067},{"__ignoreMap":401},[2068],{"type":413,"tag":501,"props":2069,"children":2070},{"class":503,"line":504},[2071,2075,2080,2084,2089,2093,2098,2103,2108,2113,2118,2122,2126,2131,2135],{"type":413,"tag":501,"props":2072,"children":2073},{"style":508},[2074],{"type":418,"value":511},{"type":413,"tag":501,"props":2076,"children":2077},{"style":508},[2078],{"type":418,"value":2079}," publicIp",{"type":413,"tag":501,"props":2081,"children":2082},{"style":519},[2083],{"type":418,"value":522},{"type":413,"tag":501,"props":2085,"children":2086},{"style":557},[2087],{"type":418,"value":2088}," Output",{"type":413,"tag":501,"props":2090,"children":2091},{"style":519},[2092],{"type":418,"value":564},{"type":413,"tag":501,"props":2094,"children":2095},{"style":567},[2096],{"type":418,"value":2097},"Create",{"type":413,"tag":501,"props":2099,"children":2100},{"style":519},[2101],{"type":418,"value":2102},"(new",{"type":413,"tag":501,"props":2104,"children":2105},{"style":508},[2106],{"type":418,"value":2107}," HttpClient",{"type":413,"tag":501,"props":2109,"children":2110},{"style":519},[2111],{"type":418,"value":2112},"().",{"type":413,"tag":501,"props":2114,"children":2115},{"style":567},[2116],{"type":418,"value":2117},"GetStringAsync",{"type":413,"tag":501,"props":2119,"children":2120},{"style":519},[2121],{"type":418,"value":575},{"type":413,"tag":501,"props":2123,"children":2124},{"style":519},[2125],{"type":418,"value":580},{"type":413,"tag":501,"props":2127,"children":2128},{"style":583},[2129],{"type":418,"value":2130},"https://api.ipify.org",{"type":413,"tag":501,"props":2132,"children":2133},{"style":519},[2134],{"type":418,"value":580},{"type":413,"tag":501,"props":2136,"children":2137},{"style":519},[2138],{"type":418,"value":2139},"));\n",{"type":413,"tag":466,"props":2141,"children":2142},{"icon":468},[2143],{"type":413,"tag":414,"props":2144,"children":2145},{},[2146,2148,2154,2156,2162,2164,2171],{"type":418,"value":2147},"You can note here that we are just using standard C# code with an ",{"type":413,"tag":443,"props":2149,"children":2151},{"className":2150},[],[2152],{"type":418,"value":2153},"HttpClient",{"type":418,"value":2155}," that makes a ",{"type":413,"tag":443,"props":2157,"children":2159},{"className":2158},[],[2160],{"type":418,"value":2161},"GET",{"type":418,"value":2163}," to the API and returns asynchronously a string. I like the fact that with Pulumi we can reuse our existing C# skills, and the libraries we are used to. If we were to do that in Terraform we would have to look in the documentation how to do HTTP calls, discover that there is an ",{"type":413,"tag":432,"props":2165,"children":2168},{"href":2166,"rel":2167},"https://registry.terraform.io/providers/hashicorp/http/latest/docs/data-sources/http",[436],[2169],{"type":418,"value":2170},"http data source",{"type":418,"value":2172}," that can be used, understand how it works (to be honest it seems quite simple but still that is not natural) and use it.",{"type":413,"tag":414,"props":2174,"children":2175},{},[2176],{"type":418,"value":2177},"Now we can enable this public IP by creating a firewall rule in the SQL Server.",{"type":413,"tag":492,"props":2179,"children":2181},{"className":494,"code":2180,"language":326,"meta":401,"style":401},"var enableLocalMachine = new FirewallRule(\"AllowLocalMachine\", new FirewallRuleArgs\n{\n    ResourceGroupName = resourceGroup.Name,\n    ServerName = sqlServer.Name,\n    StartIpAddress = publicIp,\n    EndIpAddress = publicIp\n});\n",[2182],{"type":413,"tag":443,"props":2183,"children":2184},{"__ignoreMap":401},[2185,2240,2247,2274,2301,2321,2338],{"type":413,"tag":501,"props":2186,"children":2187},{"class":503,"line":504},[2188,2192,2197,2201,2205,2210,2214,2218,2223,2227,2231,2235],{"type":413,"tag":501,"props":2189,"children":2190},{"style":508},[2191],{"type":418,"value":511},{"type":413,"tag":501,"props":2193,"children":2194},{"style":508},[2195],{"type":418,"value":2196}," enableLocalMachine",{"type":413,"tag":501,"props":2198,"children":2199},{"style":519},[2200],{"type":418,"value":522},{"type":413,"tag":501,"props":2202,"children":2203},{"style":519},[2204],{"type":418,"value":527},{"type":413,"tag":501,"props":2206,"children":2207},{"style":508},[2208],{"type":418,"value":2209}," FirewallRule",{"type":413,"tag":501,"props":2211,"children":2212},{"style":519},[2213],{"type":418,"value":575},{"type":413,"tag":501,"props":2215,"children":2216},{"style":519},[2217],{"type":418,"value":580},{"type":413,"tag":501,"props":2219,"children":2220},{"style":583},[2221],{"type":418,"value":2222},"AllowLocalMachine",{"type":413,"tag":501,"props":2224,"children":2225},{"style":519},[2226],{"type":418,"value":580},{"type":413,"tag":501,"props":2228,"children":2229},{"style":519},[2230],{"type":418,"value":704},{"type":413,"tag":501,"props":2232,"children":2233},{"style":519},[2234],{"type":418,"value":527},{"type":413,"tag":501,"props":2236,"children":2237},{"style":508},[2238],{"type":418,"value":2239}," FirewallRuleArgs\n",{"type":413,"tag":501,"props":2241,"children":2242},{"class":503,"line":540},[2243],{"type":413,"tag":501,"props":2244,"children":2245},{"style":519},[2246],{"type":418,"value":722},{"type":413,"tag":501,"props":2248,"children":2249},{"class":503,"line":598},[2250,2254,2258,2262,2266,2270],{"type":413,"tag":501,"props":2251,"children":2252},{"style":557},[2253],{"type":418,"value":951},{"type":413,"tag":501,"props":2255,"children":2256},{"style":519},[2257],{"type":418,"value":736},{"type":413,"tag":501,"props":2259,"children":2260},{"style":557},[2261],{"type":418,"value":960},{"type":413,"tag":501,"props":2263,"children":2264},{"style":519},[2265],{"type":418,"value":564},{"type":413,"tag":501,"props":2267,"children":2268},{"style":557},[2269],{"type":418,"value":969},{"type":413,"tag":501,"props":2271,"children":2272},{"style":519},[2273],{"type":418,"value":745},{"type":413,"tag":501,"props":2275,"children":2276},{"class":503,"line":649},[2277,2281,2285,2289,2293,2297],{"type":413,"tag":501,"props":2278,"children":2279},{"style":557},[2280],{"type":418,"value":1275},{"type":413,"tag":501,"props":2282,"children":2283},{"style":519},[2284],{"type":418,"value":736},{"type":413,"tag":501,"props":2286,"children":2287},{"style":557},[2288],{"type":418,"value":863},{"type":413,"tag":501,"props":2290,"children":2291},{"style":519},[2292],{"type":418,"value":564},{"type":413,"tag":501,"props":2294,"children":2295},{"style":557},[2296],{"type":418,"value":969},{"type":413,"tag":501,"props":2298,"children":2299},{"style":519},[2300],{"type":418,"value":745},{"type":413,"tag":501,"props":2302,"children":2303},{"class":503,"line":659},[2304,2309,2313,2317],{"type":413,"tag":501,"props":2305,"children":2306},{"style":557},[2307],{"type":418,"value":2308},"    StartIpAddress ",{"type":413,"tag":501,"props":2310,"children":2311},{"style":519},[2312],{"type":418,"value":736},{"type":413,"tag":501,"props":2314,"children":2315},{"style":557},[2316],{"type":418,"value":2079},{"type":413,"tag":501,"props":2318,"children":2319},{"style":519},[2320],{"type":418,"value":745},{"type":413,"tag":501,"props":2322,"children":2323},{"class":503,"line":716},[2324,2329,2333],{"type":413,"tag":501,"props":2325,"children":2326},{"style":557},[2327],{"type":418,"value":2328},"    EndIpAddress ",{"type":413,"tag":501,"props":2330,"children":2331},{"style":519},[2332],{"type":418,"value":736},{"type":413,"tag":501,"props":2334,"children":2335},{"style":557},[2336],{"type":418,"value":2337}," publicIp\n",{"type":413,"tag":501,"props":2339,"children":2340},{"class":503,"line":725},[2341],{"type":413,"tag":501,"props":2342,"children":2343},{"style":519},[2344],{"type":418,"value":803},{"type":413,"tag":1556,"props":2346,"children":2348},{"id":2347},"create-the-azure-ad-group-that-will-be-given-access-to-the-database",[2349],{"type":418,"value":2350},"Create the Azure AD group that will be given access to the database",{"type":413,"tag":414,"props":2352,"children":2353},{},[2354],{"type":418,"value":2355},"We said we wanted to grant SQL Database access to an Azure AD group that will contain in the future users and application managed identities that need access to the database. So let's create that:",{"type":413,"tag":492,"props":2357,"children":2359},{"className":494,"code":2358,"language":326,"meta":401,"style":401},"var sqlDatabaseAuthorizedGroup = new Group(\"SqlDbUsersGroup\", new GroupArgs\n{\n    DisplayName = \"SqlDbUsersGroup\",\n    SecurityEnabled = true,\n    Owners = new InputList\u003Cstring> { sqlAdAdmin.Id }\n});\n",[2360],{"type":413,"tag":443,"props":2361,"children":2362},{"__ignoreMap":401},[2363,2418,2425,2452,2472,2531],{"type":413,"tag":501,"props":2364,"children":2365},{"class":503,"line":504},[2366,2370,2375,2379,2383,2388,2392,2396,2401,2405,2409,2413],{"type":413,"tag":501,"props":2367,"children":2368},{"style":508},[2369],{"type":418,"value":511},{"type":413,"tag":501,"props":2371,"children":2372},{"style":508},[2373],{"type":418,"value":2374}," sqlDatabaseAuthorizedGroup",{"type":413,"tag":501,"props":2376,"children":2377},{"style":519},[2378],{"type":418,"value":522},{"type":413,"tag":501,"props":2380,"children":2381},{"style":519},[2382],{"type":418,"value":527},{"type":413,"tag":501,"props":2384,"children":2385},{"style":508},[2386],{"type":418,"value":2387}," Group",{"type":413,"tag":501,"props":2389,"children":2390},{"style":519},[2391],{"type":418,"value":575},{"type":413,"tag":501,"props":2393,"children":2394},{"style":519},[2395],{"type":418,"value":580},{"type":413,"tag":501,"props":2397,"children":2398},{"style":583},[2399],{"type":418,"value":2400},"SqlDbUsersGroup",{"type":413,"tag":501,"props":2402,"children":2403},{"style":519},[2404],{"type":418,"value":580},{"type":413,"tag":501,"props":2406,"children":2407},{"style":519},[2408],{"type":418,"value":704},{"type":413,"tag":501,"props":2410,"children":2411},{"style":519},[2412],{"type":418,"value":527},{"type":413,"tag":501,"props":2414,"children":2415},{"style":508},[2416],{"type":418,"value":2417}," GroupArgs\n",{"type":413,"tag":501,"props":2419,"children":2420},{"class":503,"line":540},[2421],{"type":413,"tag":501,"props":2422,"children":2423},{"style":519},[2424],{"type":418,"value":722},{"type":413,"tag":501,"props":2426,"children":2427},{"class":503,"line":598},[2428,2432,2436,2440,2444,2448],{"type":413,"tag":501,"props":2429,"children":2430},{"style":557},[2431],{"type":418,"value":775},{"type":413,"tag":501,"props":2433,"children":2434},{"style":519},[2435],{"type":418,"value":736},{"type":413,"tag":501,"props":2437,"children":2438},{"style":519},[2439],{"type":418,"value":784},{"type":413,"tag":501,"props":2441,"children":2442},{"style":583},[2443],{"type":418,"value":2400},{"type":413,"tag":501,"props":2445,"children":2446},{"style":519},[2447],{"type":418,"value":580},{"type":413,"tag":501,"props":2449,"children":2450},{"style":519},[2451],{"type":418,"value":745},{"type":413,"tag":501,"props":2453,"children":2454},{"class":503,"line":649},[2455,2460,2464,2468],{"type":413,"tag":501,"props":2456,"children":2457},{"style":557},[2458],{"type":418,"value":2459},"    SecurityEnabled ",{"type":413,"tag":501,"props":2461,"children":2462},{"style":519},[2463],{"type":418,"value":736},{"type":413,"tag":501,"props":2465,"children":2466},{"style":1075},[2467],{"type":418,"value":1078},{"type":413,"tag":501,"props":2469,"children":2470},{"style":519},[2471],{"type":418,"value":745},{"type":413,"tag":501,"props":2473,"children":2474},{"class":503,"line":659},[2475,2480,2484,2488,2493,2498,2503,2508,2513,2517,2521,2526],{"type":413,"tag":501,"props":2476,"children":2477},{"style":557},[2478],{"type":418,"value":2479},"    Owners ",{"type":413,"tag":501,"props":2481,"children":2482},{"style":519},[2483],{"type":418,"value":736},{"type":413,"tag":501,"props":2485,"children":2486},{"style":519},[2487],{"type":418,"value":527},{"type":413,"tag":501,"props":2489,"children":2490},{"style":508},[2491],{"type":418,"value":2492}," InputList",{"type":413,"tag":501,"props":2494,"children":2495},{"style":519},[2496],{"type":418,"value":2497},"\u003C",{"type":413,"tag":501,"props":2499,"children":2500},{"style":519},[2501],{"type":418,"value":2502},"string",{"type":413,"tag":501,"props":2504,"children":2505},{"style":519},[2506],{"type":418,"value":2507},">",{"type":413,"tag":501,"props":2509,"children":2510},{"style":519},[2511],{"type":418,"value":2512}," {",{"type":413,"tag":501,"props":2514,"children":2515},{"style":557},[2516],{"type":418,"value":669},{"type":413,"tag":501,"props":2518,"children":2519},{"style":519},[2520],{"type":418,"value":564},{"type":413,"tag":501,"props":2522,"children":2523},{"style":557},[2524],{"type":418,"value":2525},"Id ",{"type":413,"tag":501,"props":2527,"children":2528},{"style":519},[2529],{"type":418,"value":2530},"}\n",{"type":413,"tag":501,"props":2532,"children":2533},{"class":503,"line":716},[2534],{"type":413,"tag":501,"props":2535,"children":2536},{"style":519},[2537],{"type":418,"value":803},{"type":413,"tag":414,"props":2539,"children":2540},{},[2541],{"type":418,"value":2542},"We set the Azure SQL Server admin as the owner of the group. This way, the admin of the database can add Azure AD users to the group and they directly have the permissions configured for this group. I like authorizing an Azure AD group instead of each Azure AD user because:",{"type":413,"tag":1523,"props":2544,"children":2545},{},[2546,2551,2556],{"type":413,"tag":1527,"props":2547,"children":2548},{},[2549],{"type":418,"value":2550},"it is easier to manage a group than individual users (adding a user to a group is less work than using SQL commands to assign the correct role for each user)",{"type":413,"tag":1527,"props":2552,"children":2553},{},[2554],{"type":418,"value":2555},"you don't lose granularity of access control (you can always create several groups with different permissions if you need to)",{"type":413,"tag":1527,"props":2557,"children":2558},{},[2559],{"type":418,"value":2560},"you can ensure that your application runs with the same permissions locally (the code you debug uses your user account identity) and on Azure (the code uses the managed identity of the App Service where it is hosted) by putting users and managed identities in the same group",{"type":413,"tag":1556,"props":2562,"children":2564},{"id":2563},"assign-the-roles-to-the-azure-ad-group-using-the-command-provider",[2565],{"type":418,"value":2566},"Assign the roles to the Azure AD group using the Command provider",{"type":413,"tag":414,"props":2568,"children":2569},{},[2570,2572,2577,2579,2584],{"type":418,"value":2571},"As we already talked about, we can specify a script to run on the ",{"type":413,"tag":443,"props":2573,"children":2575},{"className":2574},[],[2576],{"type":418,"value":1952},{"type":418,"value":2578}," operation and another on the ",{"type":413,"tag":443,"props":2580,"children":2582},{"className":2581},[],[2583],{"type":418,"value":1982},{"type":418,"value":2585}," operations. To keep things simple for this sample, we will only handle the creation scenario where we will add our Azure AD group as a user of the database and give it the expected roles. We already showed the SQL Command to execute, with our new group name it becomes:",{"type":413,"tag":492,"props":2587,"children":2589},{"className":1390,"code":2588,"language":1392,"meta":401,"style":401},"CREATE USER {sqlDatabaseAuthorizedGroup.DisplayName} FROM EXTERNAL PROVIDER;\nALTER ROLE db_datareader ADD MEMBER {sqlDatabaseAuthorizedGroup.DisplayName};\nALTER ROLE db_datawriter ADD MEMBER {sqlDatabaseAuthorizedGroup.DisplayName};\nGO\n",[2590],{"type":413,"tag":443,"props":2591,"children":2592},{"__ignoreMap":401},[2593,2621,2645,2668],{"type":413,"tag":501,"props":2594,"children":2595},{"class":503,"line":504},[2596,2600,2605,2609,2613,2617],{"type":413,"tag":501,"props":2597,"children":2598},{"style":1402},[2599],{"type":418,"value":1405},{"type":413,"tag":501,"props":2601,"children":2602},{"style":557},[2603],{"type":418,"value":2604}," USER {sqlDatabaseAuthorizedGroup.DisplayName} ",{"type":413,"tag":501,"props":2606,"children":2607},{"style":1402},[2608],{"type":418,"value":1415},{"type":413,"tag":501,"props":2610,"children":2611},{"style":1402},[2612],{"type":418,"value":1420},{"type":413,"tag":501,"props":2614,"children":2615},{"style":1402},[2616],{"type":418,"value":1425},{"type":413,"tag":501,"props":2618,"children":2619},{"style":557},[2620],{"type":418,"value":1430},{"type":413,"tag":501,"props":2622,"children":2623},{"class":503,"line":540},[2624,2628,2632,2636,2640],{"type":413,"tag":501,"props":2625,"children":2626},{"style":1402},[2627],{"type":418,"value":1438},{"type":413,"tag":501,"props":2629,"children":2630},{"style":1402},[2631],{"type":418,"value":1443},{"type":413,"tag":501,"props":2633,"children":2634},{"style":557},[2635],{"type":418,"value":1448},{"type":413,"tag":501,"props":2637,"children":2638},{"style":1402},[2639],{"type":418,"value":1453},{"type":413,"tag":501,"props":2641,"children":2642},{"style":557},[2643],{"type":418,"value":2644}," MEMBER {sqlDatabaseAuthorizedGroup.DisplayName};\n",{"type":413,"tag":501,"props":2646,"children":2647},{"class":503,"line":598},[2648,2652,2656,2660,2664],{"type":413,"tag":501,"props":2649,"children":2650},{"style":1402},[2651],{"type":418,"value":1438},{"type":413,"tag":501,"props":2653,"children":2654},{"style":1402},[2655],{"type":418,"value":1443},{"type":413,"tag":501,"props":2657,"children":2658},{"style":557},[2659],{"type":418,"value":1474},{"type":413,"tag":501,"props":2661,"children":2662},{"style":1402},[2663],{"type":418,"value":1453},{"type":413,"tag":501,"props":2665,"children":2666},{"style":557},[2667],{"type":418,"value":2644},{"type":413,"tag":501,"props":2669,"children":2670},{"class":503,"line":649},[2671],{"type":413,"tag":501,"props":2672,"children":2673},{"style":1402},[2674],{"type":418,"value":1490},{"type":413,"tag":414,"props":2676,"children":2677},{},[2678,2680,2685],{"type":418,"value":2679},"The ",{"type":413,"tag":443,"props":2681,"children":2683},{"className":2682},[],[2684],{"type":418,"value":1547},{"type":418,"value":2686}," utility can be used like this to send a command on the database:",{"type":413,"tag":492,"props":2688,"children":2691},{"className":2689,"code":2690,"language":248,"meta":401,"style":401},"language-powershell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sqlcmd -S {sqlServer.Name}.database.windows.net -d {database.Name} -U {sqlAdAdmin.UserPrincipalName} -P {sqlAdAdmin.Password} -G -l 30 -Q '___SQL Command___'\n",[2692],{"type":413,"tag":443,"props":2693,"children":2694},{"__ignoreMap":401},[2695],{"type":413,"tag":501,"props":2696,"children":2697},{"class":503,"line":504},[2698,2703,2708,2713,2717,2722,2727,2732,2736,2741,2745,2750,2754,2759,2764,2768,2773,2777,2781,2786,2790,2795,2799,2803,2808,2812,2817,2822,2826,2831,2836,2841],{"type":413,"tag":501,"props":2699,"children":2700},{"style":557},[2701],{"type":418,"value":2702},"sqlcmd ",{"type":413,"tag":501,"props":2704,"children":2705},{"style":519},[2706],{"type":418,"value":2707},"-",{"type":413,"tag":501,"props":2709,"children":2710},{"style":557},[2711],{"type":418,"value":2712},"S ",{"type":413,"tag":501,"props":2714,"children":2715},{"style":519},[2716],{"type":418,"value":895},{"type":413,"tag":501,"props":2718,"children":2719},{"style":557},[2720],{"type":418,"value":2721},"sqlServer.Name",{"type":413,"tag":501,"props":2723,"children":2724},{"style":519},[2725],{"type":418,"value":2726},"}",{"type":413,"tag":501,"props":2728,"children":2729},{"style":557},[2730],{"type":418,"value":2731},".database.windows.net ",{"type":413,"tag":501,"props":2733,"children":2734},{"style":519},[2735],{"type":418,"value":2707},{"type":413,"tag":501,"props":2737,"children":2738},{"style":557},[2739],{"type":418,"value":2740},"d ",{"type":413,"tag":501,"props":2742,"children":2743},{"style":519},[2744],{"type":418,"value":895},{"type":413,"tag":501,"props":2746,"children":2747},{"style":557},[2748],{"type":418,"value":2749},"database.Name",{"type":413,"tag":501,"props":2751,"children":2752},{"style":519},[2753],{"type":418,"value":2726},{"type":413,"tag":501,"props":2755,"children":2756},{"style":519},[2757],{"type":418,"value":2758}," -",{"type":413,"tag":501,"props":2760,"children":2761},{"style":557},[2762],{"type":418,"value":2763},"U ",{"type":413,"tag":501,"props":2765,"children":2766},{"style":519},[2767],{"type":418,"value":895},{"type":413,"tag":501,"props":2769,"children":2770},{"style":557},[2771],{"type":418,"value":2772},"sqlAdAdmin.UserPrincipalName",{"type":413,"tag":501,"props":2774,"children":2775},{"style":519},[2776],{"type":418,"value":2726},{"type":413,"tag":501,"props":2778,"children":2779},{"style":519},[2780],{"type":418,"value":2758},{"type":413,"tag":501,"props":2782,"children":2783},{"style":557},[2784],{"type":418,"value":2785},"P ",{"type":413,"tag":501,"props":2787,"children":2788},{"style":519},[2789],{"type":418,"value":895},{"type":413,"tag":501,"props":2791,"children":2792},{"style":557},[2793],{"type":418,"value":2794},"sqlAdAdmin.Password",{"type":413,"tag":501,"props":2796,"children":2797},{"style":519},[2798],{"type":418,"value":2726},{"type":413,"tag":501,"props":2800,"children":2801},{"style":519},[2802],{"type":418,"value":2758},{"type":413,"tag":501,"props":2804,"children":2805},{"style":557},[2806],{"type":418,"value":2807},"G ",{"type":413,"tag":501,"props":2809,"children":2810},{"style":519},[2811],{"type":418,"value":2707},{"type":413,"tag":501,"props":2813,"children":2814},{"style":557},[2815],{"type":418,"value":2816},"l ",{"type":413,"tag":501,"props":2818,"children":2819},{"style":1402},[2820],{"type":418,"value":2821},"30",{"type":413,"tag":501,"props":2823,"children":2824},{"style":519},[2825],{"type":418,"value":2758},{"type":413,"tag":501,"props":2827,"children":2828},{"style":557},[2829],{"type":418,"value":2830},"Q ",{"type":413,"tag":501,"props":2832,"children":2833},{"style":519},[2834],{"type":418,"value":2835},"'",{"type":413,"tag":501,"props":2837,"children":2838},{"style":583},[2839],{"type":418,"value":2840},"___SQL Command___",{"type":413,"tag":501,"props":2842,"children":2843},{"style":519},[2844],{"type":418,"value":2845},"'\n",{"type":413,"tag":414,"props":2847,"children":2848},{},[2849,2851,2858,2860,2865],{"type":418,"value":2850},"You can check the ",{"type":413,"tag":432,"props":2852,"children":2855},{"href":2853,"rel":2854},"https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-ver15#sqlcmd-commands",[436],[2856],{"type":418,"value":2857},"documentation",{"type":418,"value":2859}," to learn more about how to use ",{"type":413,"tag":443,"props":2861,"children":2863},{"className":2862},[],[2864],{"type":418,"value":1547},{"type":418,"value":2866}," but that is quite simple: we are just specifying to send a command line query on our database using Azure Active Directory to authenticate.",{"type":413,"tag":414,"props":2868,"children":2869},{},[2870],{"type":418,"value":2871},"If we use all that with our Command provider, we get the following C# code.",{"type":413,"tag":492,"props":2873,"children":2875},{"className":494,"code":2874,"language":326,"meta":401,"style":401},"var authorizeAdGroup = new Command(\"AuthorizeAdGroup\", new CommandArgs\n{\n    Create = Output.Format($\"sqlcmd -S {sqlServer.Name}.database.windows.net -d {database.Name} -U {sqlAdAdmin.UserPrincipalName} -P {sqlAdAdmin.Password} -G -l 30 -Q 'CREATE USER {sqlDatabaseAuthorizedGroup.DisplayName} FROM EXTERNAL PROVIDER; ALTER ROLE db_datareader ADD MEMBER {sqlDatabaseAuthorizedGroup.DisplayName}; ALTER ROLE db_datawriter ADD MEMBER {sqlDatabaseAuthorizedGroup.DisplayName};'\"),\n    Interpreter = new InputList\u003Cstring>\n    {\n        \"pwsh\",\n        \"-c\"\n    }\n});\n",[2876],{"type":413,"tag":443,"props":2877,"children":2878},{"__ignoreMap":401},[2879,2934,2941,3167,3200,3207,3228,3244,3251],{"type":413,"tag":501,"props":2880,"children":2881},{"class":503,"line":504},[2882,2886,2891,2895,2899,2904,2908,2912,2917,2921,2925,2929],{"type":413,"tag":501,"props":2883,"children":2884},{"style":508},[2885],{"type":418,"value":511},{"type":413,"tag":501,"props":2887,"children":2888},{"style":508},[2889],{"type":418,"value":2890}," authorizeAdGroup",{"type":413,"tag":501,"props":2892,"children":2893},{"style":519},[2894],{"type":418,"value":522},{"type":413,"tag":501,"props":2896,"children":2897},{"style":519},[2898],{"type":418,"value":527},{"type":413,"tag":501,"props":2900,"children":2901},{"style":508},[2902],{"type":418,"value":2903}," Command",{"type":413,"tag":501,"props":2905,"children":2906},{"style":519},[2907],{"type":418,"value":575},{"type":413,"tag":501,"props":2909,"children":2910},{"style":519},[2911],{"type":418,"value":580},{"type":413,"tag":501,"props":2913,"children":2914},{"style":583},[2915],{"type":418,"value":2916},"AuthorizeAdGroup",{"type":413,"tag":501,"props":2918,"children":2919},{"style":519},[2920],{"type":418,"value":580},{"type":413,"tag":501,"props":2922,"children":2923},{"style":519},[2924],{"type":418,"value":704},{"type":413,"tag":501,"props":2926,"children":2927},{"style":519},[2928],{"type":418,"value":527},{"type":413,"tag":501,"props":2930,"children":2931},{"style":508},[2932],{"type":418,"value":2933}," CommandArgs\n",{"type":413,"tag":501,"props":2935,"children":2936},{"class":503,"line":540},[2937],{"type":413,"tag":501,"props":2938,"children":2939},{"style":519},[2940],{"type":418,"value":722},{"type":413,"tag":501,"props":2942,"children":2943},{"class":503,"line":598},[2944,2949,2953,2957,2961,2966,2970,2974,2979,2983,2988,2992,2996,3000,3005,3009,3013,3017,3021,3025,3030,3034,3038,3042,3046,3050,3055,3059,3063,3067,3072,3076,3081,3085,3090,3094,3099,3103,3108,3112,3116,3120,3124,3128,3133,3137,3141,3145,3149,3153,3158,3162],{"type":413,"tag":501,"props":2945,"children":2946},{"style":557},[2947],{"type":418,"value":2948},"    Create ",{"type":413,"tag":501,"props":2950,"children":2951},{"style":519},[2952],{"type":418,"value":736},{"type":413,"tag":501,"props":2954,"children":2955},{"style":557},[2956],{"type":418,"value":2088},{"type":413,"tag":501,"props":2958,"children":2959},{"style":519},[2960],{"type":418,"value":564},{"type":413,"tag":501,"props":2962,"children":2963},{"style":567},[2964],{"type":418,"value":2965},"Format",{"type":413,"tag":501,"props":2967,"children":2968},{"style":519},[2969],{"type":418,"value":575},{"type":413,"tag":501,"props":2971,"children":2972},{"style":519},[2973],{"type":418,"value":885},{"type":413,"tag":501,"props":2975,"children":2976},{"style":583},[2977],{"type":418,"value":2978},"sqlcmd -S ",{"type":413,"tag":501,"props":2980,"children":2981},{"style":519},[2982],{"type":418,"value":895},{"type":413,"tag":501,"props":2984,"children":2985},{"style":557},[2986],{"type":418,"value":2987},"sqlServer",{"type":413,"tag":501,"props":2989,"children":2990},{"style":519},[2991],{"type":418,"value":564},{"type":413,"tag":501,"props":2993,"children":2994},{"style":557},[2995],{"type":418,"value":969},{"type":413,"tag":501,"props":2997,"children":2998},{"style":519},[2999],{"type":418,"value":2726},{"type":413,"tag":501,"props":3001,"children":3002},{"style":583},[3003],{"type":418,"value":3004},".database.windows.net -d ",{"type":413,"tag":501,"props":3006,"children":3007},{"style":519},[3008],{"type":418,"value":895},{"type":413,"tag":501,"props":3010,"children":3011},{"style":557},[3012],{"type":418,"value":1723},{"type":413,"tag":501,"props":3014,"children":3015},{"style":519},[3016],{"type":418,"value":564},{"type":413,"tag":501,"props":3018,"children":3019},{"style":557},[3020],{"type":418,"value":969},{"type":413,"tag":501,"props":3022,"children":3023},{"style":519},[3024],{"type":418,"value":2726},{"type":413,"tag":501,"props":3026,"children":3027},{"style":583},[3028],{"type":418,"value":3029}," -U ",{"type":413,"tag":501,"props":3031,"children":3032},{"style":519},[3033],{"type":418,"value":895},{"type":413,"tag":501,"props":3035,"children":3036},{"style":557},[3037],{"type":418,"value":586},{"type":413,"tag":501,"props":3039,"children":3040},{"style":519},[3041],{"type":418,"value":564},{"type":413,"tag":501,"props":3043,"children":3044},{"style":557},[3045],{"type":418,"value":1027},{"type":413,"tag":501,"props":3047,"children":3048},{"style":519},[3049],{"type":418,"value":2726},{"type":413,"tag":501,"props":3051,"children":3052},{"style":583},[3053],{"type":418,"value":3054}," -P ",{"type":413,"tag":501,"props":3056,"children":3057},{"style":519},[3058],{"type":418,"value":895},{"type":413,"tag":501,"props":3060,"children":3061},{"style":557},[3062],{"type":418,"value":586},{"type":413,"tag":501,"props":3064,"children":3065},{"style":519},[3066],{"type":418,"value":564},{"type":413,"tag":501,"props":3068,"children":3069},{"style":557},[3070],{"type":418,"value":3071},"Password",{"type":413,"tag":501,"props":3073,"children":3074},{"style":519},[3075],{"type":418,"value":2726},{"type":413,"tag":501,"props":3077,"children":3078},{"style":583},[3079],{"type":418,"value":3080}," -G -l 30 -Q 'CREATE USER ",{"type":413,"tag":501,"props":3082,"children":3083},{"style":519},[3084],{"type":418,"value":895},{"type":413,"tag":501,"props":3086,"children":3087},{"style":557},[3088],{"type":418,"value":3089},"sqlDatabaseAuthorizedGroup",{"type":413,"tag":501,"props":3091,"children":3092},{"style":519},[3093],{"type":418,"value":564},{"type":413,"tag":501,"props":3095,"children":3096},{"style":557},[3097],{"type":418,"value":3098},"DisplayName",{"type":413,"tag":501,"props":3100,"children":3101},{"style":519},[3102],{"type":418,"value":2726},{"type":413,"tag":501,"props":3104,"children":3105},{"style":583},[3106],{"type":418,"value":3107}," FROM EXTERNAL PROVIDER; ALTER ROLE db_datareader ADD MEMBER ",{"type":413,"tag":501,"props":3109,"children":3110},{"style":519},[3111],{"type":418,"value":895},{"type":413,"tag":501,"props":3113,"children":3114},{"style":557},[3115],{"type":418,"value":3089},{"type":413,"tag":501,"props":3117,"children":3118},{"style":519},[3119],{"type":418,"value":564},{"type":413,"tag":501,"props":3121,"children":3122},{"style":557},[3123],{"type":418,"value":3098},{"type":413,"tag":501,"props":3125,"children":3126},{"style":519},[3127],{"type":418,"value":2726},{"type":413,"tag":501,"props":3129,"children":3130},{"style":583},[3131],{"type":418,"value":3132},"; ALTER ROLE db_datawriter ADD MEMBER ",{"type":413,"tag":501,"props":3134,"children":3135},{"style":519},[3136],{"type":418,"value":895},{"type":413,"tag":501,"props":3138,"children":3139},{"style":557},[3140],{"type":418,"value":3089},{"type":413,"tag":501,"props":3142,"children":3143},{"style":519},[3144],{"type":418,"value":564},{"type":413,"tag":501,"props":3146,"children":3147},{"style":557},[3148],{"type":418,"value":3098},{"type":413,"tag":501,"props":3150,"children":3151},{"style":519},[3152],{"type":418,"value":2726},{"type":413,"tag":501,"props":3154,"children":3155},{"style":583},[3156],{"type":418,"value":3157},";'",{"type":413,"tag":501,"props":3159,"children":3160},{"style":519},[3161],{"type":418,"value":580},{"type":413,"tag":501,"props":3163,"children":3164},{"style":519},[3165],{"type":418,"value":3166},"),\n",{"type":413,"tag":501,"props":3168,"children":3169},{"class":503,"line":649},[3170,3175,3179,3183,3187,3191,3195],{"type":413,"tag":501,"props":3171,"children":3172},{"style":557},[3173],{"type":418,"value":3174},"    Interpreter ",{"type":413,"tag":501,"props":3176,"children":3177},{"style":519},[3178],{"type":418,"value":736},{"type":413,"tag":501,"props":3180,"children":3181},{"style":519},[3182],{"type":418,"value":527},{"type":413,"tag":501,"props":3184,"children":3185},{"style":508},[3186],{"type":418,"value":2492},{"type":413,"tag":501,"props":3188,"children":3189},{"style":519},[3190],{"type":418,"value":2497},{"type":413,"tag":501,"props":3192,"children":3193},{"style":519},[3194],{"type":418,"value":2502},{"type":413,"tag":501,"props":3196,"children":3197},{"style":519},[3198],{"type":418,"value":3199},">\n",{"type":413,"tag":501,"props":3201,"children":3202},{"class":503,"line":659},[3203],{"type":413,"tag":501,"props":3204,"children":3205},{"style":519},[3206],{"type":418,"value":1002},{"type":413,"tag":501,"props":3208,"children":3209},{"class":503,"line":716},[3210,3215,3220,3224],{"type":413,"tag":501,"props":3211,"children":3212},{"style":519},[3213],{"type":418,"value":3214},"        \"",{"type":413,"tag":501,"props":3216,"children":3217},{"style":583},[3218],{"type":418,"value":3219},"pwsh",{"type":413,"tag":501,"props":3221,"children":3222},{"style":519},[3223],{"type":418,"value":580},{"type":413,"tag":501,"props":3225,"children":3226},{"style":519},[3227],{"type":418,"value":745},{"type":413,"tag":501,"props":3229,"children":3230},{"class":503,"line":725},[3231,3235,3240],{"type":413,"tag":501,"props":3232,"children":3233},{"style":519},[3234],{"type":418,"value":3214},{"type":413,"tag":501,"props":3236,"children":3237},{"style":583},[3238],{"type":418,"value":3239},"-c",{"type":413,"tag":501,"props":3241,"children":3242},{"style":519},[3243],{"type":418,"value":794},{"type":413,"tag":501,"props":3245,"children":3246},{"class":503,"line":748},[3247],{"type":413,"tag":501,"props":3248,"children":3249},{"style":519},[3250],{"type":418,"value":1356},{"type":413,"tag":501,"props":3252,"children":3253},{"class":503,"line":769},[3254],{"type":413,"tag":501,"props":3255,"children":3256},{"style":519},[3257],{"type":418,"value":803},{"type":413,"tag":414,"props":3259,"children":3260},{},[3261],{"type":418,"value":3262},"As you can see, we can specify a specific interpreter to use (PowerShell here).",{"type":413,"tag":466,"props":3264,"children":3265},{"icon":468},[3266],{"type":413,"tag":414,"props":3267,"children":3268},{},[3269,3271,3278,3280,3286,3288,3294],{"type":418,"value":3270},"Don't do like me and forget that our variables are ",{"type":413,"tag":432,"props":3272,"children":3275},{"href":3273,"rel":3274},"https://www.pulumi.com/docs/intro/concepts/inputs-outputs/#inputs-and-outputs",[436],[3276],{"type":418,"value":3277},"outputs",{"type":418,"value":3279}," (only fully known when the infrastructure resource is completely provisioned). Because of that it is necessary to use the ",{"type":413,"tag":443,"props":3281,"children":3283},{"className":3282},[],[3284],{"type":418,"value":3285},"Output.Format",{"type":418,"value":3287}," method for string interpolation instead of using the C# operator ",{"type":413,"tag":443,"props":3289,"children":3291},{"className":3290},[],[3292],{"type":418,"value":3293},"$",{"type":418,"value":3295},". Thanks to the community on Slack for helping me on that one because with the Command provider not logging the errors details I had a hard time on this.",{"type":413,"tag":1556,"props":3297,"children":3299},{"id":3298},"results",[3300],{"type":418,"value":3301},"Results",{"type":413,"tag":414,"props":3303,"children":3304},{},[3305,3307,3312,3313,3318],{"type":418,"value":3306},"And that's it! We now have created the Azure AD group as an external user in the database and assigned it the ",{"type":413,"tag":443,"props":3308,"children":3310},{"className":3309},[],[3311],{"type":418,"value":1501},{"type":418,"value":1503},{"type":413,"tag":443,"props":3314,"children":3316},{"className":3315},[],[3317],{"type":418,"value":1509},{"type":418,"value":3319}," roles.\nHere is what it looks like in Azure Data Studio:",{"type":413,"tag":414,"props":3321,"children":3322},{},[3323],{"type":413,"tag":1580,"props":3324,"children":3328},{"alt":3325,"className":3326,"src":3327},"SQL query listing database members and roles in Azure Data Studio.",[1584,1585],"/posts/images/sqldatabase_ad_azuredatastudio.png",[],{"type":413,"tag":420,"props":3330,"children":3332},{"id":3331},"conclusion",[3333],{"type":418,"value":3334},"Conclusion",{"type":413,"tag":414,"props":3336,"children":3337},{},[3338,3340,3346],{"type":418,"value":3339},"This article is a bit long because I explain all the steps and possibilities but the complete code is not very big or complex. You can find it in this ",{"type":413,"tag":432,"props":3341,"children":3344},{"href":3342,"rel":3343},"https://github.com/TechWatching/SqlDatabaseWithAzureAd",[436],[3345],{"type":418,"value":1617},{"type":418,"value":564},{"type":413,"tag":414,"props":3348,"children":3349},{},[3350],{"type":418,"value":3351},"I did not see that many articles on the web that talk about using Azure Active Directory authentication for an Azure SQL Database, and even less that showed how to properly configure it using Infrastructure as Code. Yet, I think it's an important thing to do to properly secure your Azure SQL database. So I hope you enjoyed it and learn something. Whether you use Azure CLI, Bicep, ARM Templates, Terraform, or Pulumi, don't hesitate to use Azure AD authentication on your Azure SQL Database, for me that is the right and secure way to go.",{"type":413,"tag":414,"props":3353,"children":3354},{},[3355],{"type":418,"value":3356},"As you have seen in this article, even when there is no provider for your custom resource or task, there are always several solutions to do what you want with Pulumi. Some are more elegant, some are more complex than others but you will always find a way and you will not be limited by the platform.",{"type":413,"tag":414,"props":3358,"children":3359},{},[3360],{"type":418,"value":3361},"A big thank you to the Pulumi community that gave me some insights on how to configure Azure AD authentication on a database properly using Pulumi. Without the help of some people in the Pulumi Slack or the GitHub Issues/Discussions I would not have been able to write this article. Indeed some ideas and solutions are directly inspired by people's answers to my questions. This article is my way of contributing back and helping others that would have similar questions.",{"type":413,"tag":3363,"props":3364,"children":3365},"style",{},[3366],{"type":418,"value":3367},"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":401,"searchDepth":540,"depth":540,"links":3369},[3370,3371,3372,3373,3379,3385],{"id":422,"depth":540,"text":425},{"id":482,"depth":540,"text":485},{"id":836,"depth":540,"text":839},{"id":1366,"depth":540,"text":1369,"children":3374},[3375,3376,3377],{"id":1558,"depth":598,"text":1561},{"id":1659,"depth":598,"text":1662},{"id":1877,"depth":598,"text":3378},"Command provider with the sqlcmd utility",{"id":2019,"depth":540,"text":2022,"children":3380},[3381,3382,3383,3384],{"id":2044,"depth":598,"text":2047},{"id":2347,"depth":598,"text":2350},{"id":2563,"depth":598,"text":2566},{"id":3298,"depth":598,"text":3301},{"id":3331,"depth":540,"text":3334},"markdown","content:1.posts:35.sqldatabase-active-directory-authent.md","content","1.posts/35.sqldatabase-active-directory-authent.md","md",{"_path":76,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":75,"description":3392,"date":3393,"image":3394,"badge":3396,"tags":3397,"body":3398,"_type":3386,"_id":5377,"_source":3388,"_file":5378,"_extension":3390},"If you are using Azure Functions chances are you are using the setting AzureWebJobsStorage in your Function App configuration. And it is quite likely that the value of this setting which is a secret is stored in a non-secured way directly in your Function App configuration, available to anyone who has access to this configuration. But do not worry, we will see in this article how we can make your Function App more secure by removing this secret.","2021-09-15T00:00:00.000Z",{"src":3395},"/images/lightning_2.jpg",{"label":266},[257,312,315,252,228],{"type":410,"children":3399,"toc":5366},[3400,3413,3418,3424,3437,3449,3458,3464,3469,3478,3483,3489,3503,3512,3525,3539,3555,3561,3574,3580,3585,3603,3608,3614,3628,3633,3742,3755,3966,3971,4245,4257,4941,4963,5187,5195,5214,5228,5234,5239,5276,5285,5298,5303,5333,5338,5346,5352,5357,5362],{"type":413,"tag":414,"props":3401,"children":3402},{},[3403,3405,3411],{"type":418,"value":3404},"If you are using Azure Functions chances are you are using the setting ",{"type":413,"tag":443,"props":3406,"children":3408},{"className":3407},[],[3409],{"type":418,"value":3410},"AzureWebJobsStorage",{"type":418,"value":3412}," in your Function App configuration. And it is quite likely that the value of this setting which is a secret is stored in a non-secured way directly in your Function App configuration, available to anyone who has access to this configuration. But do not worry, we will see in this article how we can make your Function App more secure by removing this secret.",{"type":413,"tag":414,"props":3414,"children":3415},{},[3416],{"type":418,"value":3417},"But first, let's start at the beginning.",{"type":413,"tag":420,"props":3419,"children":3421},{"id":3420},"what-is-this-azurewebjobsstorage-setting",[3422],{"type":418,"value":3423},"What is this AzureWebJobsStorage setting?",{"type":413,"tag":414,"props":3425,"children":3426},{},[3427,3429,3435],{"type":418,"value":3428},"As explained in the ",{"type":413,"tag":432,"props":3430,"children":3433},{"href":3431,"rel":3432},"https://docs.microsoft.com/en-us/azure/azure-functions/storage-considerations#storage-account-requirements",[436],[3434],{"type":418,"value":2857},{"type":418,"value":3436},", Azure Functions \"rely on Azure Storage for operations such as managing triggers and logging function executions\" which explains why you must associate a storage account to your Function App when you create one.",{"type":413,"tag":414,"props":3438,"children":3439},{},[3440,3442,3447],{"type":418,"value":3441},"By default when you create a Function App with its storage account from Azure Portal, the setting ",{"type":413,"tag":443,"props":3443,"children":3445},{"className":3444},[],[3446],{"type":418,"value":3410},{"type":418,"value":3448}," is automatically created in the Function App configuration and its value contains the secret connection string of the storage account. Thanks to that it will allow your Function App to have access to this storage and to work properly.",{"type":413,"tag":414,"props":3450,"children":3451},{},[3452],{"type":413,"tag":1580,"props":3453,"children":3457},{"alt":3454,"className":3455,"src":3456},"AzureWebJobsStorage setting with a secret value in Function App settings.",[1584,1585],"/posts/images/functionsidentity_portal_1.png",[],{"type":413,"tag":420,"props":3459,"children":3461},{"id":3460},"why-azurewebjobsstorage-poses-a-security-risk",[3462],{"type":418,"value":3463},"Why AzureWebJobsStorage poses a security risk?",{"type":413,"tag":414,"props":3465,"children":3466},{},[3467],{"type":418,"value":3468},"App settings of your Function App are stored encrypted in Azure so having secrets in a Function App configuration in Azure does not seem a big security threat. Yet,  secrets in Azure application settings will be available to anyone who has access to the configuration screen of your Function App (or to Kudu) which does not seem a great idea. Moreover in the application settings of a Function App, there is no proper access monitoring, alerting, and auditing as you would have in an Azure Key Vault. So your secret is not really \"safe\" there.",{"type":413,"tag":414,"props":3470,"children":3471},{},[3472],{"type":413,"tag":1580,"props":3473,"children":3477},{"alt":3474,"className":3475,"src":3476},"Padlock on a keyboard.",[1584,1585],"/posts/images/functionsidentity_padlock_1.jpgpng",[],{"type":413,"tag":414,"props":3479,"children":3480},{},[3481],{"type":418,"value":3482},"To avoid having someone gaining access to your storage account without you knowing, you probably do not want your storage account connection string to stay in a Function App configuration on Azure Portal.",{"type":413,"tag":420,"props":3484,"children":3486},{"id":3485},"what-can-we-do-about-it",[3487],{"type":418,"value":3488},"What can we do about it?",{"type":413,"tag":414,"props":3490,"children":3491},{},[3492,3494,3501],{"type":418,"value":3493},"A solution could be to store the AzureWebJobsStorage secret value in an Azure Key Vault and use a ",{"type":413,"tag":432,"props":3495,"children":3498},{"href":3496,"rel":3497},"https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references",[436],[3499],{"type":418,"value":3500},"Key Vault reference",{"type":418,"value":3502}," to link the secret in Key Vault to the AzureWebJobsStorage setting like on the example below.",{"type":413,"tag":414,"props":3504,"children":3505},{},[3506],{"type":413,"tag":1580,"props":3507,"children":3511},{"alt":3508,"className":3509,"src":3510},"AzureWebJobsStorage setting as a keyvault reference in Function App settings.",[1584,1585],"/posts/images/functionsidentity_portal_2.png",[],{"type":413,"tag":414,"props":3513,"children":3514},{},[3515,3517,3523],{"type":418,"value":3516},"Another solution that is far more interesting I think (as it does not require any secret) is to assign the Storage Blob Data Owner role to your Function App identity and to replace the AzureWebJobsStorage connection string setting by the setting ",{"type":413,"tag":443,"props":3518,"children":3520},{"className":3519},[],[3521],{"type":418,"value":3522},"AzureWebJobsStorage__accountName",{"type":418,"value":3524}," that only contains the name of the storage account and no secret value at all.",{"type":413,"tag":414,"props":3526,"children":3527},{},[3528,3530,3537],{"type":418,"value":3529},"If you want more details about connecting to the storage with the Function App identity you can find it ",{"type":413,"tag":432,"props":3531,"children":3534},{"href":3532,"rel":3533},"https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference#connecting-to-host-storage-with-an-identity",[436],[3535],{"type":418,"value":3536},"here",{"type":418,"value":3538},". There is no point for me to paraphrase the documentation just to explain how you can set this up. However, I can show you how to implement that using Infrastructure as Code.",{"type":413,"tag":466,"props":3540,"children":3541},{"icon":468},[3542],{"type":413,"tag":414,"props":3543,"children":3544},{},[3545,3547,3553],{"type":418,"value":3546},"If you have read ",{"type":413,"tag":432,"props":3548,"children":3550},{"href":434,"rel":3549},[436],[3551],{"type":418,"value":3552},"my article",{"type":418,"value":3554}," about connecting to an Azure SQL Database using Azure AD to authenticate instead of a secret connection, you probably know that I am not a big fan of secrets when we can avoid using them. From a security perspective, I think it is always a gain to remove the need for secrets while ensuring a resource can only be accessed by authorized people/applications.",{"type":413,"tag":420,"props":3556,"children":3558},{"id":3557},"how-to-configure-a-function-app-to-work-with-its-storage-account-without-a-secret-connection-string",[3559],{"type":418,"value":3560},"How to configure a Function App to work with its storage account without a secret connection string?",{"type":413,"tag":414,"props":3562,"children":3563},{},[3564,3566,3572],{"type":418,"value":3565},"To do that, I will use ",{"type":413,"tag":432,"props":3567,"children":3570},{"href":3568,"rel":3569},"https://www.pulumi.com/",[436],[3571],{"type":418,"value":312},{"type":418,"value":3573}," which is an Infrastructure as Code platform that uses programming languages instead of DSL to deploy infrastructure. As I am usually programming in C# for my application code, I will use C# as well for my infrastructure code.",{"type":413,"tag":1556,"props":3575,"children":3577},{"id":3576},"what-resources-do-we-need-to-create",[3578],{"type":418,"value":3579},"What resources do we need to create?",{"type":413,"tag":414,"props":3581,"children":3582},{},[3583],{"type":418,"value":3584},"We need to create 3 different Azure resources:",{"type":413,"tag":1523,"props":3586,"children":3587},{},[3588,3593,3598],{"type":413,"tag":1527,"props":3589,"children":3590},{},[3591],{"type":418,"value":3592},"a consumption App Service Plan",{"type":413,"tag":1527,"props":3594,"children":3595},{},[3596],{"type":418,"value":3597},"a Function App",{"type":413,"tag":1527,"props":3599,"children":3600},{},[3601],{"type":418,"value":3602},"a Storage Account",{"type":413,"tag":414,"props":3604,"children":3605},{},[3606],{"type":418,"value":3607},"A resource group will also be created to contain these resources.\nAnd we will also need to assign the Storage Blob Data Owner role to the Function App, so to create a Role Assignment \"resource\".",{"type":413,"tag":1556,"props":3609,"children":3611},{"id":3610},"what-the-infrastructure-code-looks-like",[3612],{"type":418,"value":3613},"What the infrastructure code looks like?",{"type":413,"tag":414,"props":3615,"children":3616},{},[3617,3619,3626],{"type":418,"value":3618},"The infrastructure code looks like standard C# code, but it describes the Azure resources we need using the ",{"type":413,"tag":432,"props":3620,"children":3623},{"href":3621,"rel":3622},"https://www.pulumi.com/blog/full-coverage-of-azure-resources-with-azure-native/",[436],[3624],{"type":418,"value":3625},"Azure Native provider",{"type":418,"value":3627}," for Pulumi.",{"type":413,"tag":414,"props":3629,"children":3630},{},[3631],{"type":418,"value":3632},"Declaring a resource group is quite easy. Here we use C# string interpolation to build the resource group name from the project name and the stack name (two Pulumi notions that correspond to the name of the project and the environment):",{"type":413,"tag":492,"props":3634,"children":3636},{"className":494,"code":3635,"language":326,"meta":401,"style":401},"var resourceGroup = new ResourceGroup($\"rg-{Deployment.Instance.ProjectName}-{Deployment.Instance.StackName}\");\n",[3637],{"type":413,"tag":443,"props":3638,"children":3639},{"__ignoreMap":401},[3640],{"type":413,"tag":501,"props":3641,"children":3642},{"class":503,"line":504},[3643,3647,3651,3655,3659,3664,3668,3672,3677,3681,3685,3689,3693,3697,3702,3706,3710,3714,3718,3722,3726,3730,3734,3738],{"type":413,"tag":501,"props":3644,"children":3645},{"style":508},[3646],{"type":418,"value":511},{"type":413,"tag":501,"props":3648,"children":3649},{"style":508},[3650],{"type":418,"value":960},{"type":413,"tag":501,"props":3652,"children":3653},{"style":519},[3654],{"type":418,"value":522},{"type":413,"tag":501,"props":3656,"children":3657},{"style":519},[3658],{"type":418,"value":527},{"type":413,"tag":501,"props":3660,"children":3661},{"style":508},[3662],{"type":418,"value":3663}," ResourceGroup",{"type":413,"tag":501,"props":3665,"children":3666},{"style":519},[3667],{"type":418,"value":575},{"type":413,"tag":501,"props":3669,"children":3670},{"style":519},[3671],{"type":418,"value":885},{"type":413,"tag":501,"props":3673,"children":3674},{"style":583},[3675],{"type":418,"value":3676},"rg-",{"type":413,"tag":501,"props":3678,"children":3679},{"style":519},[3680],{"type":418,"value":895},{"type":413,"tag":501,"props":3682,"children":3683},{"style":557},[3684],{"type":418,"value":900},{"type":413,"tag":501,"props":3686,"children":3687},{"style":519},[3688],{"type":418,"value":564},{"type":413,"tag":501,"props":3690,"children":3691},{"style":557},[3692],{"type":418,"value":909},{"type":413,"tag":501,"props":3694,"children":3695},{"style":519},[3696],{"type":418,"value":564},{"type":413,"tag":501,"props":3698,"children":3699},{"style":557},[3700],{"type":418,"value":3701},"ProjectName",{"type":413,"tag":501,"props":3703,"children":3704},{"style":519},[3705],{"type":418,"value":2726},{"type":413,"tag":501,"props":3707,"children":3708},{"style":583},[3709],{"type":418,"value":2707},{"type":413,"tag":501,"props":3711,"children":3712},{"style":519},[3713],{"type":418,"value":895},{"type":413,"tag":501,"props":3715,"children":3716},{"style":557},[3717],{"type":418,"value":900},{"type":413,"tag":501,"props":3719,"children":3720},{"style":519},[3721],{"type":418,"value":564},{"type":413,"tag":501,"props":3723,"children":3724},{"style":557},[3725],{"type":418,"value":909},{"type":413,"tag":501,"props":3727,"children":3728},{"style":519},[3729],{"type":418,"value":564},{"type":413,"tag":501,"props":3731,"children":3732},{"style":557},[3733],{"type":418,"value":918},{"type":413,"tag":501,"props":3735,"children":3736},{"style":519},[3737],{"type":418,"value":923},{"type":413,"tag":501,"props":3739,"children":3740},{"style":519},[3741],{"type":418,"value":595},{"type":413,"tag":414,"props":3743,"children":3744},{},[3745,3747,3753],{"type":418,"value":3746},"To declare the resource group in which we want to create the storage account, we can use the property name of variable ",{"type":413,"tag":443,"props":3748,"children":3750},{"className":3749},[],[3751],{"type":418,"value":3752},"resourceGroup",{"type":418,"value":3754}," previously declared. We can see that for some arguments like the SKU names, Pulumi has types to help us choose between different possible values instead of specifying a magic string. It is not always the case but it is pretty handy when such things are available.",{"type":413,"tag":492,"props":3756,"children":3758},{"className":494,"code":3757,"language":326,"meta":401,"style":401},"var storageAccount = new StorageAccount($\"stnosecretfun{Deployment.Instance.StackName}\", new StorageAccountArgs\n{\n    ResourceGroupName = resourceGroup.Name,\n    Sku = new SkuArgs\n    {\n        Name = SkuName.Standard_LRS\n    },\n    Kind = Kind.StorageV2\n});\n",[3759],{"type":413,"tag":443,"props":3760,"children":3761},{"__ignoreMap":401},[3762,3841,3848,3875,3894,3901,3926,3933,3959],{"type":413,"tag":501,"props":3763,"children":3764},{"class":503,"line":504},[3765,3769,3774,3778,3782,3787,3791,3795,3800,3804,3808,3812,3816,3820,3824,3828,3832,3836],{"type":413,"tag":501,"props":3766,"children":3767},{"style":508},[3768],{"type":418,"value":511},{"type":413,"tag":501,"props":3770,"children":3771},{"style":508},[3772],{"type":418,"value":3773}," storageAccount",{"type":413,"tag":501,"props":3775,"children":3776},{"style":519},[3777],{"type":418,"value":522},{"type":413,"tag":501,"props":3779,"children":3780},{"style":519},[3781],{"type":418,"value":527},{"type":413,"tag":501,"props":3783,"children":3784},{"style":508},[3785],{"type":418,"value":3786}," StorageAccount",{"type":413,"tag":501,"props":3788,"children":3789},{"style":519},[3790],{"type":418,"value":575},{"type":413,"tag":501,"props":3792,"children":3793},{"style":519},[3794],{"type":418,"value":885},{"type":413,"tag":501,"props":3796,"children":3797},{"style":583},[3798],{"type":418,"value":3799},"stnosecretfun",{"type":413,"tag":501,"props":3801,"children":3802},{"style":519},[3803],{"type":418,"value":895},{"type":413,"tag":501,"props":3805,"children":3806},{"style":557},[3807],{"type":418,"value":900},{"type":413,"tag":501,"props":3809,"children":3810},{"style":519},[3811],{"type":418,"value":564},{"type":413,"tag":501,"props":3813,"children":3814},{"style":557},[3815],{"type":418,"value":909},{"type":413,"tag":501,"props":3817,"children":3818},{"style":519},[3819],{"type":418,"value":564},{"type":413,"tag":501,"props":3821,"children":3822},{"style":557},[3823],{"type":418,"value":918},{"type":413,"tag":501,"props":3825,"children":3826},{"style":519},[3827],{"type":418,"value":923},{"type":413,"tag":501,"props":3829,"children":3830},{"style":519},[3831],{"type":418,"value":704},{"type":413,"tag":501,"props":3833,"children":3834},{"style":519},[3835],{"type":418,"value":527},{"type":413,"tag":501,"props":3837,"children":3838},{"style":508},[3839],{"type":418,"value":3840}," StorageAccountArgs\n",{"type":413,"tag":501,"props":3842,"children":3843},{"class":503,"line":540},[3844],{"type":413,"tag":501,"props":3845,"children":3846},{"style":519},[3847],{"type":418,"value":722},{"type":413,"tag":501,"props":3849,"children":3850},{"class":503,"line":598},[3851,3855,3859,3863,3867,3871],{"type":413,"tag":501,"props":3852,"children":3853},{"style":557},[3854],{"type":418,"value":951},{"type":413,"tag":501,"props":3856,"children":3857},{"style":519},[3858],{"type":418,"value":736},{"type":413,"tag":501,"props":3860,"children":3861},{"style":557},[3862],{"type":418,"value":960},{"type":413,"tag":501,"props":3864,"children":3865},{"style":519},[3866],{"type":418,"value":564},{"type":413,"tag":501,"props":3868,"children":3869},{"style":557},[3870],{"type":418,"value":969},{"type":413,"tag":501,"props":3872,"children":3873},{"style":519},[3874],{"type":418,"value":745},{"type":413,"tag":501,"props":3876,"children":3877},{"class":503,"line":649},[3878,3882,3886,3890],{"type":413,"tag":501,"props":3879,"children":3880},{"style":557},[3881],{"type":418,"value":1303},{"type":413,"tag":501,"props":3883,"children":3884},{"style":519},[3885],{"type":418,"value":736},{"type":413,"tag":501,"props":3887,"children":3888},{"style":519},[3889],{"type":418,"value":527},{"type":413,"tag":501,"props":3891,"children":3892},{"style":508},[3893],{"type":418,"value":1316},{"type":413,"tag":501,"props":3895,"children":3896},{"class":503,"line":659},[3897],{"type":413,"tag":501,"props":3898,"children":3899},{"style":519},[3900],{"type":418,"value":1002},{"type":413,"tag":501,"props":3902,"children":3903},{"class":503,"line":716},[3904,3908,3912,3917,3921],{"type":413,"tag":501,"props":3905,"children":3906},{"style":557},[3907],{"type":418,"value":1331},{"type":413,"tag":501,"props":3909,"children":3910},{"style":519},[3911],{"type":418,"value":736},{"type":413,"tag":501,"props":3913,"children":3914},{"style":557},[3915],{"type":418,"value":3916}," SkuName",{"type":413,"tag":501,"props":3918,"children":3919},{"style":519},[3920],{"type":418,"value":564},{"type":413,"tag":501,"props":3922,"children":3923},{"style":557},[3924],{"type":418,"value":3925},"Standard_LRS\n",{"type":413,"tag":501,"props":3927,"children":3928},{"class":503,"line":725},[3929],{"type":413,"tag":501,"props":3930,"children":3931},{"style":519},[3932],{"type":418,"value":1151},{"type":413,"tag":501,"props":3934,"children":3935},{"class":503,"line":748},[3936,3941,3945,3950,3954],{"type":413,"tag":501,"props":3937,"children":3938},{"style":557},[3939],{"type":418,"value":3940},"    Kind ",{"type":413,"tag":501,"props":3942,"children":3943},{"style":519},[3944],{"type":418,"value":736},{"type":413,"tag":501,"props":3946,"children":3947},{"style":557},[3948],{"type":418,"value":3949}," Kind",{"type":413,"tag":501,"props":3951,"children":3952},{"style":519},[3953],{"type":418,"value":564},{"type":413,"tag":501,"props":3955,"children":3956},{"style":557},[3957],{"type":418,"value":3958},"StorageV2\n",{"type":413,"tag":501,"props":3960,"children":3961},{"class":503,"line":769},[3962],{"type":413,"tag":501,"props":3963,"children":3964},{"style":519},[3965],{"type":418,"value":803},{"type":413,"tag":414,"props":3967,"children":3968},{},[3969],{"type":418,"value":3970},"This is the way of declaring a consumption App Service Plan:",{"type":413,"tag":492,"props":3972,"children":3974},{"className":494,"code":3973,"language":326,"meta":401,"style":401},"var appServicePlan = new AppServicePlan($\"plan-{Deployment.Instance.ProjectName}-{Deployment.Instance.StackName}\", new AppServicePlanArgs\n{\n    ResourceGroupName = resourceGroup.Name,\n    Kind = \"Windows\",\n    Sku = new SkuDescriptionArgs\n    {\n        Tier = \"Dynamic\",\n        Name = \"Y1\"\n    }\n});\n",[3975],{"type":413,"tag":443,"props":3976,"children":3977},{"__ignoreMap":401},[3978,4089,4096,4123,4151,4171,4178,4207,4231,4238],{"type":413,"tag":501,"props":3979,"children":3980},{"class":503,"line":504},[3981,3985,3990,3994,3998,4003,4007,4011,4016,4020,4024,4028,4032,4036,4040,4044,4048,4052,4056,4060,4064,4068,4072,4076,4080,4084],{"type":413,"tag":501,"props":3982,"children":3983},{"style":508},[3984],{"type":418,"value":511},{"type":413,"tag":501,"props":3986,"children":3987},{"style":508},[3988],{"type":418,"value":3989}," appServicePlan",{"type":413,"tag":501,"props":3991,"children":3992},{"style":519},[3993],{"type":418,"value":522},{"type":413,"tag":501,"props":3995,"children":3996},{"style":519},[3997],{"type":418,"value":527},{"type":413,"tag":501,"props":3999,"children":4000},{"style":508},[4001],{"type":418,"value":4002}," AppServicePlan",{"type":413,"tag":501,"props":4004,"children":4005},{"style":519},[4006],{"type":418,"value":575},{"type":413,"tag":501,"props":4008,"children":4009},{"style":519},[4010],{"type":418,"value":885},{"type":413,"tag":501,"props":4012,"children":4013},{"style":583},[4014],{"type":418,"value":4015},"plan-",{"type":413,"tag":501,"props":4017,"children":4018},{"style":519},[4019],{"type":418,"value":895},{"type":413,"tag":501,"props":4021,"children":4022},{"style":557},[4023],{"type":418,"value":900},{"type":413,"tag":501,"props":4025,"children":4026},{"style":519},[4027],{"type":418,"value":564},{"type":413,"tag":501,"props":4029,"children":4030},{"style":557},[4031],{"type":418,"value":909},{"type":413,"tag":501,"props":4033,"children":4034},{"style":519},[4035],{"type":418,"value":564},{"type":413,"tag":501,"props":4037,"children":4038},{"style":557},[4039],{"type":418,"value":3701},{"type":413,"tag":501,"props":4041,"children":4042},{"style":519},[4043],{"type":418,"value":2726},{"type":413,"tag":501,"props":4045,"children":4046},{"style":583},[4047],{"type":418,"value":2707},{"type":413,"tag":501,"props":4049,"children":4050},{"style":519},[4051],{"type":418,"value":895},{"type":413,"tag":501,"props":4053,"children":4054},{"style":557},[4055],{"type":418,"value":900},{"type":413,"tag":501,"props":4057,"children":4058},{"style":519},[4059],{"type":418,"value":564},{"type":413,"tag":501,"props":4061,"children":4062},{"style":557},[4063],{"type":418,"value":909},{"type":413,"tag":501,"props":4065,"children":4066},{"style":519},[4067],{"type":418,"value":564},{"type":413,"tag":501,"props":4069,"children":4070},{"style":557},[4071],{"type":418,"value":918},{"type":413,"tag":501,"props":4073,"children":4074},{"style":519},[4075],{"type":418,"value":923},{"type":413,"tag":501,"props":4077,"children":4078},{"style":519},[4079],{"type":418,"value":704},{"type":413,"tag":501,"props":4081,"children":4082},{"style":519},[4083],{"type":418,"value":527},{"type":413,"tag":501,"props":4085,"children":4086},{"style":508},[4087],{"type":418,"value":4088}," AppServicePlanArgs\n",{"type":413,"tag":501,"props":4090,"children":4091},{"class":503,"line":540},[4092],{"type":413,"tag":501,"props":4093,"children":4094},{"style":519},[4095],{"type":418,"value":722},{"type":413,"tag":501,"props":4097,"children":4098},{"class":503,"line":598},[4099,4103,4107,4111,4115,4119],{"type":413,"tag":501,"props":4100,"children":4101},{"style":557},[4102],{"type":418,"value":951},{"type":413,"tag":501,"props":4104,"children":4105},{"style":519},[4106],{"type":418,"value":736},{"type":413,"tag":501,"props":4108,"children":4109},{"style":557},[4110],{"type":418,"value":960},{"type":413,"tag":501,"props":4112,"children":4113},{"style":519},[4114],{"type":418,"value":564},{"type":413,"tag":501,"props":4116,"children":4117},{"style":557},[4118],{"type":418,"value":969},{"type":413,"tag":501,"props":4120,"children":4121},{"style":519},[4122],{"type":418,"value":745},{"type":413,"tag":501,"props":4124,"children":4125},{"class":503,"line":649},[4126,4130,4134,4138,4143,4147],{"type":413,"tag":501,"props":4127,"children":4128},{"style":557},[4129],{"type":418,"value":3940},{"type":413,"tag":501,"props":4131,"children":4132},{"style":519},[4133],{"type":418,"value":736},{"type":413,"tag":501,"props":4135,"children":4136},{"style":519},[4137],{"type":418,"value":784},{"type":413,"tag":501,"props":4139,"children":4140},{"style":583},[4141],{"type":418,"value":4142},"Windows",{"type":413,"tag":501,"props":4144,"children":4145},{"style":519},[4146],{"type":418,"value":580},{"type":413,"tag":501,"props":4148,"children":4149},{"style":519},[4150],{"type":418,"value":745},{"type":413,"tag":501,"props":4152,"children":4153},{"class":503,"line":659},[4154,4158,4162,4166],{"type":413,"tag":501,"props":4155,"children":4156},{"style":557},[4157],{"type":418,"value":1303},{"type":413,"tag":501,"props":4159,"children":4160},{"style":519},[4161],{"type":418,"value":736},{"type":413,"tag":501,"props":4163,"children":4164},{"style":519},[4165],{"type":418,"value":527},{"type":413,"tag":501,"props":4167,"children":4168},{"style":508},[4169],{"type":418,"value":4170}," SkuDescriptionArgs\n",{"type":413,"tag":501,"props":4172,"children":4173},{"class":503,"line":716},[4174],{"type":413,"tag":501,"props":4175,"children":4176},{"style":519},[4177],{"type":418,"value":1002},{"type":413,"tag":501,"props":4179,"children":4180},{"class":503,"line":725},[4181,4186,4190,4194,4199,4203],{"type":413,"tag":501,"props":4182,"children":4183},{"style":557},[4184],{"type":418,"value":4185},"        Tier ",{"type":413,"tag":501,"props":4187,"children":4188},{"style":519},[4189],{"type":418,"value":736},{"type":413,"tag":501,"props":4191,"children":4192},{"style":519},[4193],{"type":418,"value":784},{"type":413,"tag":501,"props":4195,"children":4196},{"style":583},[4197],{"type":418,"value":4198},"Dynamic",{"type":413,"tag":501,"props":4200,"children":4201},{"style":519},[4202],{"type":418,"value":580},{"type":413,"tag":501,"props":4204,"children":4205},{"style":519},[4206],{"type":418,"value":745},{"type":413,"tag":501,"props":4208,"children":4209},{"class":503,"line":748},[4210,4214,4218,4222,4227],{"type":413,"tag":501,"props":4211,"children":4212},{"style":557},[4213],{"type":418,"value":1331},{"type":413,"tag":501,"props":4215,"children":4216},{"style":519},[4217],{"type":418,"value":736},{"type":413,"tag":501,"props":4219,"children":4220},{"style":519},[4221],{"type":418,"value":784},{"type":413,"tag":501,"props":4223,"children":4224},{"style":583},[4225],{"type":418,"value":4226},"Y1",{"type":413,"tag":501,"props":4228,"children":4229},{"style":519},[4230],{"type":418,"value":794},{"type":413,"tag":501,"props":4232,"children":4233},{"class":503,"line":769},[4234],{"type":413,"tag":501,"props":4235,"children":4236},{"style":519},[4237],{"type":418,"value":1356},{"type":413,"tag":501,"props":4239,"children":4240},{"class":503,"line":797},[4241],{"type":413,"tag":501,"props":4242,"children":4243},{"style":519},[4244],{"type":418,"value":803},{"type":413,"tag":414,"props":4246,"children":4247},{},[4248,4250,4255],{"type":418,"value":4249},"In Azure APIs, a FunctionApp is just a WebApp of a special kind \"FunctionApp\". You can notice that we enabled the System Managed Identity on the Function App by setting the Identity property. And as expected we added an app setting ",{"type":413,"tag":443,"props":4251,"children":4253},{"className":4252},[],[4254],{"type":418,"value":3522},{"type":418,"value":4256}," whose value is the name of the storage account.",{"type":413,"tag":492,"props":4258,"children":4260},{"className":494,"code":4259,"language":326,"meta":401,"style":401},"var functionApp = new WebApp($\"func-nosecret-{Deployment.Instance.StackName}\", new WebAppArgs\n{\n    Kind = \"FunctionApp\",\n    ResourceGroupName = resourceGroup.Name,\n    ServerFarmId = appServicePlan.Id,\n    Identity = new ManagedServiceIdentityArgs\n    {\n        Type = Pulumi.AzureNative.Web.ManagedServiceIdentityType.SystemAssigned\n    },\n    SiteConfig = new SiteConfigArgs\n    {\n        AppSettings = new[]\n        {\n            new NameValuePairArgs\n            {\n                Name = \"runtime\",\n                Value = \"dotnet\",\n            },\n            new NameValuePairArgs\n            {\n                Name = \"FUNCTIONS_WORKER_RUNTIME\",\n                Value = \"dotnet\",\n            },\n            new NameValuePairArgs\n            {\n                Name = \"FUNCTIONS_EXTENSION_VERSION\",\n                Value = \"~4\"\n            },\n            new NameValuePairArgs\n            {\n                Name = \"AzureWebJobsStorage__accountName\",\n                Value = storageAccount.Name\n            }\n        },\n    },\n});\n",[4261],{"type":413,"tag":443,"props":4262,"children":4263},{"__ignoreMap":401},[4264,4343,4350,4378,4405,4433,4454,4461,4514,4521,4542,4549,4566,4575,4589,4598,4628,4658,4667,4679,4687,4716,4744,4752,4764,4772,4801,4826,4834,4846,4854,4882,4907,4916,4925,4933],{"type":413,"tag":501,"props":4265,"children":4266},{"class":503,"line":504},[4267,4271,4276,4280,4284,4289,4293,4297,4302,4306,4310,4314,4318,4322,4326,4330,4334,4338],{"type":413,"tag":501,"props":4268,"children":4269},{"style":508},[4270],{"type":418,"value":511},{"type":413,"tag":501,"props":4272,"children":4273},{"style":508},[4274],{"type":418,"value":4275}," functionApp",{"type":413,"tag":501,"props":4277,"children":4278},{"style":519},[4279],{"type":418,"value":522},{"type":413,"tag":501,"props":4281,"children":4282},{"style":519},[4283],{"type":418,"value":527},{"type":413,"tag":501,"props":4285,"children":4286},{"style":508},[4287],{"type":418,"value":4288}," WebApp",{"type":413,"tag":501,"props":4290,"children":4291},{"style":519},[4292],{"type":418,"value":575},{"type":413,"tag":501,"props":4294,"children":4295},{"style":519},[4296],{"type":418,"value":885},{"type":413,"tag":501,"props":4298,"children":4299},{"style":583},[4300],{"type":418,"value":4301},"func-nosecret-",{"type":413,"tag":501,"props":4303,"children":4304},{"style":519},[4305],{"type":418,"value":895},{"type":413,"tag":501,"props":4307,"children":4308},{"style":557},[4309],{"type":418,"value":900},{"type":413,"tag":501,"props":4311,"children":4312},{"style":519},[4313],{"type":418,"value":564},{"type":413,"tag":501,"props":4315,"children":4316},{"style":557},[4317],{"type":418,"value":909},{"type":413,"tag":501,"props":4319,"children":4320},{"style":519},[4321],{"type":418,"value":564},{"type":413,"tag":501,"props":4323,"children":4324},{"style":557},[4325],{"type":418,"value":918},{"type":413,"tag":501,"props":4327,"children":4328},{"style":519},[4329],{"type":418,"value":923},{"type":413,"tag":501,"props":4331,"children":4332},{"style":519},[4333],{"type":418,"value":704},{"type":413,"tag":501,"props":4335,"children":4336},{"style":519},[4337],{"type":418,"value":527},{"type":413,"tag":501,"props":4339,"children":4340},{"style":508},[4341],{"type":418,"value":4342}," WebAppArgs\n",{"type":413,"tag":501,"props":4344,"children":4345},{"class":503,"line":540},[4346],{"type":413,"tag":501,"props":4347,"children":4348},{"style":519},[4349],{"type":418,"value":722},{"type":413,"tag":501,"props":4351,"children":4352},{"class":503,"line":598},[4353,4357,4361,4365,4370,4374],{"type":413,"tag":501,"props":4354,"children":4355},{"style":557},[4356],{"type":418,"value":3940},{"type":413,"tag":501,"props":4358,"children":4359},{"style":519},[4360],{"type":418,"value":736},{"type":413,"tag":501,"props":4362,"children":4363},{"style":519},[4364],{"type":418,"value":784},{"type":413,"tag":501,"props":4366,"children":4367},{"style":583},[4368],{"type":418,"value":4369},"FunctionApp",{"type":413,"tag":501,"props":4371,"children":4372},{"style":519},[4373],{"type":418,"value":580},{"type":413,"tag":501,"props":4375,"children":4376},{"style":519},[4377],{"type":418,"value":745},{"type":413,"tag":501,"props":4379,"children":4380},{"class":503,"line":649},[4381,4385,4389,4393,4397,4401],{"type":413,"tag":501,"props":4382,"children":4383},{"style":557},[4384],{"type":418,"value":951},{"type":413,"tag":501,"props":4386,"children":4387},{"style":519},[4388],{"type":418,"value":736},{"type":413,"tag":501,"props":4390,"children":4391},{"style":557},[4392],{"type":418,"value":960},{"type":413,"tag":501,"props":4394,"children":4395},{"style":519},[4396],{"type":418,"value":564},{"type":413,"tag":501,"props":4398,"children":4399},{"style":557},[4400],{"type":418,"value":969},{"type":413,"tag":501,"props":4402,"children":4403},{"style":519},[4404],{"type":418,"value":745},{"type":413,"tag":501,"props":4406,"children":4407},{"class":503,"line":659},[4408,4413,4417,4421,4425,4429],{"type":413,"tag":501,"props":4409,"children":4410},{"style":557},[4411],{"type":418,"value":4412},"    ServerFarmId ",{"type":413,"tag":501,"props":4414,"children":4415},{"style":519},[4416],{"type":418,"value":736},{"type":413,"tag":501,"props":4418,"children":4419},{"style":557},[4420],{"type":418,"value":3989},{"type":413,"tag":501,"props":4422,"children":4423},{"style":519},[4424],{"type":418,"value":564},{"type":413,"tag":501,"props":4426,"children":4427},{"style":557},[4428],{"type":418,"value":1056},{"type":413,"tag":501,"props":4430,"children":4431},{"style":519},[4432],{"type":418,"value":745},{"type":413,"tag":501,"props":4434,"children":4435},{"class":503,"line":716},[4436,4441,4445,4449],{"type":413,"tag":501,"props":4437,"children":4438},{"style":557},[4439],{"type":418,"value":4440},"    Identity ",{"type":413,"tag":501,"props":4442,"children":4443},{"style":519},[4444],{"type":418,"value":736},{"type":413,"tag":501,"props":4446,"children":4447},{"style":519},[4448],{"type":418,"value":527},{"type":413,"tag":501,"props":4450,"children":4451},{"style":508},[4452],{"type":418,"value":4453}," ManagedServiceIdentityArgs\n",{"type":413,"tag":501,"props":4455,"children":4456},{"class":503,"line":725},[4457],{"type":413,"tag":501,"props":4458,"children":4459},{"style":519},[4460],{"type":418,"value":1002},{"type":413,"tag":501,"props":4462,"children":4463},{"class":503,"line":748},[4464,4469,4473,4478,4482,4487,4491,4496,4500,4505,4509],{"type":413,"tag":501,"props":4465,"children":4466},{"style":557},[4467],{"type":418,"value":4468},"        Type ",{"type":413,"tag":501,"props":4470,"children":4471},{"style":519},[4472],{"type":418,"value":736},{"type":413,"tag":501,"props":4474,"children":4475},{"style":557},[4476],{"type":418,"value":4477}," Pulumi",{"type":413,"tag":501,"props":4479,"children":4480},{"style":519},[4481],{"type":418,"value":564},{"type":413,"tag":501,"props":4483,"children":4484},{"style":557},[4485],{"type":418,"value":4486},"AzureNative",{"type":413,"tag":501,"props":4488,"children":4489},{"style":519},[4490],{"type":418,"value":564},{"type":413,"tag":501,"props":4492,"children":4493},{"style":557},[4494],{"type":418,"value":4495},"Web",{"type":413,"tag":501,"props":4497,"children":4498},{"style":519},[4499],{"type":418,"value":564},{"type":413,"tag":501,"props":4501,"children":4502},{"style":557},[4503],{"type":418,"value":4504},"ManagedServiceIdentityType",{"type":413,"tag":501,"props":4506,"children":4507},{"style":519},[4508],{"type":418,"value":564},{"type":413,"tag":501,"props":4510,"children":4511},{"style":557},[4512],{"type":418,"value":4513},"SystemAssigned\n",{"type":413,"tag":501,"props":4515,"children":4516},{"class":503,"line":769},[4517],{"type":413,"tag":501,"props":4518,"children":4519},{"style":519},[4520],{"type":418,"value":1151},{"type":413,"tag":501,"props":4522,"children":4523},{"class":503,"line":797},[4524,4529,4533,4537],{"type":413,"tag":501,"props":4525,"children":4526},{"style":557},[4527],{"type":418,"value":4528},"    SiteConfig ",{"type":413,"tag":501,"props":4530,"children":4531},{"style":519},[4532],{"type":418,"value":736},{"type":413,"tag":501,"props":4534,"children":4535},{"style":519},[4536],{"type":418,"value":527},{"type":413,"tag":501,"props":4538,"children":4539},{"style":508},[4540],{"type":418,"value":4541}," SiteConfigArgs\n",{"type":413,"tag":501,"props":4543,"children":4544},{"class":503,"line":1145},[4545],{"type":413,"tag":501,"props":4546,"children":4547},{"style":519},[4548],{"type":418,"value":1002},{"type":413,"tag":501,"props":4550,"children":4551},{"class":503,"line":1154},[4552,4557,4561],{"type":413,"tag":501,"props":4553,"children":4554},{"style":557},[4555],{"type":418,"value":4556},"        AppSettings ",{"type":413,"tag":501,"props":4558,"children":4559},{"style":519},[4560],{"type":418,"value":736},{"type":413,"tag":501,"props":4562,"children":4563},{"style":519},[4564],{"type":418,"value":4565}," new[]\n",{"type":413,"tag":501,"props":4567,"children":4569},{"class":503,"line":4568},13,[4570],{"type":413,"tag":501,"props":4571,"children":4572},{"style":519},[4573],{"type":418,"value":4574},"        {\n",{"type":413,"tag":501,"props":4576,"children":4578},{"class":503,"line":4577},14,[4579,4584],{"type":413,"tag":501,"props":4580,"children":4581},{"style":519},[4582],{"type":418,"value":4583},"            new",{"type":413,"tag":501,"props":4585,"children":4586},{"style":508},[4587],{"type":418,"value":4588}," NameValuePairArgs\n",{"type":413,"tag":501,"props":4590,"children":4592},{"class":503,"line":4591},15,[4593],{"type":413,"tag":501,"props":4594,"children":4595},{"style":519},[4596],{"type":418,"value":4597},"            {\n",{"type":413,"tag":501,"props":4599,"children":4601},{"class":503,"line":4600},16,[4602,4607,4611,4615,4620,4624],{"type":413,"tag":501,"props":4603,"children":4604},{"style":557},[4605],{"type":418,"value":4606},"                Name ",{"type":413,"tag":501,"props":4608,"children":4609},{"style":519},[4610],{"type":418,"value":736},{"type":413,"tag":501,"props":4612,"children":4613},{"style":519},[4614],{"type":418,"value":784},{"type":413,"tag":501,"props":4616,"children":4617},{"style":583},[4618],{"type":418,"value":4619},"runtime",{"type":413,"tag":501,"props":4621,"children":4622},{"style":519},[4623],{"type":418,"value":580},{"type":413,"tag":501,"props":4625,"children":4626},{"style":519},[4627],{"type":418,"value":745},{"type":413,"tag":501,"props":4629,"children":4631},{"class":503,"line":4630},17,[4632,4637,4641,4645,4650,4654],{"type":413,"tag":501,"props":4633,"children":4634},{"style":557},[4635],{"type":418,"value":4636},"                Value ",{"type":413,"tag":501,"props":4638,"children":4639},{"style":519},[4640],{"type":418,"value":736},{"type":413,"tag":501,"props":4642,"children":4643},{"style":519},[4644],{"type":418,"value":784},{"type":413,"tag":501,"props":4646,"children":4647},{"style":583},[4648],{"type":418,"value":4649},"dotnet",{"type":413,"tag":501,"props":4651,"children":4652},{"style":519},[4653],{"type":418,"value":580},{"type":413,"tag":501,"props":4655,"children":4656},{"style":519},[4657],{"type":418,"value":745},{"type":413,"tag":501,"props":4659,"children":4661},{"class":503,"line":4660},18,[4662],{"type":413,"tag":501,"props":4663,"children":4664},{"style":519},[4665],{"type":418,"value":4666},"            },\n",{"type":413,"tag":501,"props":4668,"children":4670},{"class":503,"line":4669},19,[4671,4675],{"type":413,"tag":501,"props":4672,"children":4673},{"style":519},[4674],{"type":418,"value":4583},{"type":413,"tag":501,"props":4676,"children":4677},{"style":508},[4678],{"type":418,"value":4588},{"type":413,"tag":501,"props":4680,"children":4682},{"class":503,"line":4681},20,[4683],{"type":413,"tag":501,"props":4684,"children":4685},{"style":519},[4686],{"type":418,"value":4597},{"type":413,"tag":501,"props":4688,"children":4690},{"class":503,"line":4689},21,[4691,4695,4699,4703,4708,4712],{"type":413,"tag":501,"props":4692,"children":4693},{"style":557},[4694],{"type":418,"value":4606},{"type":413,"tag":501,"props":4696,"children":4697},{"style":519},[4698],{"type":418,"value":736},{"type":413,"tag":501,"props":4700,"children":4701},{"style":519},[4702],{"type":418,"value":784},{"type":413,"tag":501,"props":4704,"children":4705},{"style":583},[4706],{"type":418,"value":4707},"FUNCTIONS_WORKER_RUNTIME",{"type":413,"tag":501,"props":4709,"children":4710},{"style":519},[4711],{"type":418,"value":580},{"type":413,"tag":501,"props":4713,"children":4714},{"style":519},[4715],{"type":418,"value":745},{"type":413,"tag":501,"props":4717,"children":4719},{"class":503,"line":4718},22,[4720,4724,4728,4732,4736,4740],{"type":413,"tag":501,"props":4721,"children":4722},{"style":557},[4723],{"type":418,"value":4636},{"type":413,"tag":501,"props":4725,"children":4726},{"style":519},[4727],{"type":418,"value":736},{"type":413,"tag":501,"props":4729,"children":4730},{"style":519},[4731],{"type":418,"value":784},{"type":413,"tag":501,"props":4733,"children":4734},{"style":583},[4735],{"type":418,"value":4649},{"type":413,"tag":501,"props":4737,"children":4738},{"style":519},[4739],{"type":418,"value":580},{"type":413,"tag":501,"props":4741,"children":4742},{"style":519},[4743],{"type":418,"value":745},{"type":413,"tag":501,"props":4745,"children":4747},{"class":503,"line":4746},23,[4748],{"type":413,"tag":501,"props":4749,"children":4750},{"style":519},[4751],{"type":418,"value":4666},{"type":413,"tag":501,"props":4753,"children":4755},{"class":503,"line":4754},24,[4756,4760],{"type":413,"tag":501,"props":4757,"children":4758},{"style":519},[4759],{"type":418,"value":4583},{"type":413,"tag":501,"props":4761,"children":4762},{"style":508},[4763],{"type":418,"value":4588},{"type":413,"tag":501,"props":4765,"children":4767},{"class":503,"line":4766},25,[4768],{"type":413,"tag":501,"props":4769,"children":4770},{"style":519},[4771],{"type":418,"value":4597},{"type":413,"tag":501,"props":4773,"children":4775},{"class":503,"line":4774},26,[4776,4780,4784,4788,4793,4797],{"type":413,"tag":501,"props":4777,"children":4778},{"style":557},[4779],{"type":418,"value":4606},{"type":413,"tag":501,"props":4781,"children":4782},{"style":519},[4783],{"type":418,"value":736},{"type":413,"tag":501,"props":4785,"children":4786},{"style":519},[4787],{"type":418,"value":784},{"type":413,"tag":501,"props":4789,"children":4790},{"style":583},[4791],{"type":418,"value":4792},"FUNCTIONS_EXTENSION_VERSION",{"type":413,"tag":501,"props":4794,"children":4795},{"style":519},[4796],{"type":418,"value":580},{"type":413,"tag":501,"props":4798,"children":4799},{"style":519},[4800],{"type":418,"value":745},{"type":413,"tag":501,"props":4802,"children":4804},{"class":503,"line":4803},27,[4805,4809,4813,4817,4822],{"type":413,"tag":501,"props":4806,"children":4807},{"style":557},[4808],{"type":418,"value":4636},{"type":413,"tag":501,"props":4810,"children":4811},{"style":519},[4812],{"type":418,"value":736},{"type":413,"tag":501,"props":4814,"children":4815},{"style":519},[4816],{"type":418,"value":784},{"type":413,"tag":501,"props":4818,"children":4819},{"style":583},[4820],{"type":418,"value":4821},"~4",{"type":413,"tag":501,"props":4823,"children":4824},{"style":519},[4825],{"type":418,"value":794},{"type":413,"tag":501,"props":4827,"children":4829},{"class":503,"line":4828},28,[4830],{"type":413,"tag":501,"props":4831,"children":4832},{"style":519},[4833],{"type":418,"value":4666},{"type":413,"tag":501,"props":4835,"children":4837},{"class":503,"line":4836},29,[4838,4842],{"type":413,"tag":501,"props":4839,"children":4840},{"style":519},[4841],{"type":418,"value":4583},{"type":413,"tag":501,"props":4843,"children":4844},{"style":508},[4845],{"type":418,"value":4588},{"type":413,"tag":501,"props":4847,"children":4849},{"class":503,"line":4848},30,[4850],{"type":413,"tag":501,"props":4851,"children":4852},{"style":519},[4853],{"type":418,"value":4597},{"type":413,"tag":501,"props":4855,"children":4857},{"class":503,"line":4856},31,[4858,4862,4866,4870,4874,4878],{"type":413,"tag":501,"props":4859,"children":4860},{"style":557},[4861],{"type":418,"value":4606},{"type":413,"tag":501,"props":4863,"children":4864},{"style":519},[4865],{"type":418,"value":736},{"type":413,"tag":501,"props":4867,"children":4868},{"style":519},[4869],{"type":418,"value":784},{"type":413,"tag":501,"props":4871,"children":4872},{"style":583},[4873],{"type":418,"value":3522},{"type":413,"tag":501,"props":4875,"children":4876},{"style":519},[4877],{"type":418,"value":580},{"type":413,"tag":501,"props":4879,"children":4880},{"style":519},[4881],{"type":418,"value":745},{"type":413,"tag":501,"props":4883,"children":4885},{"class":503,"line":4884},32,[4886,4890,4894,4898,4902],{"type":413,"tag":501,"props":4887,"children":4888},{"style":557},[4889],{"type":418,"value":4636},{"type":413,"tag":501,"props":4891,"children":4892},{"style":519},[4893],{"type":418,"value":736},{"type":413,"tag":501,"props":4895,"children":4896},{"style":557},[4897],{"type":418,"value":3773},{"type":413,"tag":501,"props":4899,"children":4900},{"style":519},[4901],{"type":418,"value":564},{"type":413,"tag":501,"props":4903,"children":4904},{"style":557},[4905],{"type":418,"value":4906},"Name\n",{"type":413,"tag":501,"props":4908,"children":4910},{"class":503,"line":4909},33,[4911],{"type":413,"tag":501,"props":4912,"children":4913},{"style":519},[4914],{"type":418,"value":4915},"            }\n",{"type":413,"tag":501,"props":4917,"children":4919},{"class":503,"line":4918},34,[4920],{"type":413,"tag":501,"props":4921,"children":4922},{"style":519},[4923],{"type":418,"value":4924},"        },\n",{"type":413,"tag":501,"props":4926,"children":4928},{"class":503,"line":4927},35,[4929],{"type":413,"tag":501,"props":4930,"children":4931},{"style":519},[4932],{"type":418,"value":1151},{"type":413,"tag":501,"props":4934,"children":4936},{"class":503,"line":4935},36,[4937],{"type":413,"tag":501,"props":4938,"children":4939},{"style":519},[4940],{"type":418,"value":803},{"type":413,"tag":414,"props":4942,"children":4943},{},[4944,4946,4953,4955,4961],{"type":418,"value":4945},"The last thing to do is to assign the role Storage Blob Data Owner to the Function App. To find the resource id I needed I looked at ",{"type":413,"tag":432,"props":4947,"children":4950},{"href":4948,"rel":4949},"https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles",[436],[4951],{"type":418,"value":4952},"this page of the Microsoft documentation",{"type":418,"value":4954}," but I hope that in the future Pulumi will provide an ",{"type":413,"tag":443,"props":4956,"children":4958},{"className":4957},[],[4959],{"type":418,"value":4960},"enum",{"type":418,"value":4962}," or something like that with the possible values to make that easier to find and assign.",{"type":413,"tag":492,"props":4964,"children":4966},{"className":494,"code":4965,"language":326,"meta":401,"style":401},"var storageBlobDataOwnerRole = new RoleAssignment(\"storageBlobDataOwner\", new RoleAssignmentArgs\n{\n    PrincipalId = functionApp.Identity.Apply(i => i.PrincipalId),\n    PrincipalType = PrincipalType.ServicePrincipal,\n    RoleDefinitionId = \"/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b\",\n    Scope = storageAccount.Id\n});\n",[4967],{"type":413,"tag":443,"props":4968,"children":4969},{"__ignoreMap":401},[4970,5025,5032,5097,5126,5155,5180],{"type":413,"tag":501,"props":4971,"children":4972},{"class":503,"line":504},[4973,4977,4982,4986,4990,4995,4999,5003,5008,5012,5016,5020],{"type":413,"tag":501,"props":4974,"children":4975},{"style":508},[4976],{"type":418,"value":511},{"type":413,"tag":501,"props":4978,"children":4979},{"style":508},[4980],{"type":418,"value":4981}," storageBlobDataOwnerRole",{"type":413,"tag":501,"props":4983,"children":4984},{"style":519},[4985],{"type":418,"value":522},{"type":413,"tag":501,"props":4987,"children":4988},{"style":519},[4989],{"type":418,"value":527},{"type":413,"tag":501,"props":4991,"children":4992},{"style":508},[4993],{"type":418,"value":4994}," RoleAssignment",{"type":413,"tag":501,"props":4996,"children":4997},{"style":519},[4998],{"type":418,"value":575},{"type":413,"tag":501,"props":5000,"children":5001},{"style":519},[5002],{"type":418,"value":580},{"type":413,"tag":501,"props":5004,"children":5005},{"style":583},[5006],{"type":418,"value":5007},"storageBlobDataOwner",{"type":413,"tag":501,"props":5009,"children":5010},{"style":519},[5011],{"type":418,"value":580},{"type":413,"tag":501,"props":5013,"children":5014},{"style":519},[5015],{"type":418,"value":704},{"type":413,"tag":501,"props":5017,"children":5018},{"style":519},[5019],{"type":418,"value":527},{"type":413,"tag":501,"props":5021,"children":5022},{"style":508},[5023],{"type":418,"value":5024}," RoleAssignmentArgs\n",{"type":413,"tag":501,"props":5026,"children":5027},{"class":503,"line":540},[5028],{"type":413,"tag":501,"props":5029,"children":5030},{"style":519},[5031],{"type":418,"value":722},{"type":413,"tag":501,"props":5033,"children":5034},{"class":503,"line":598},[5035,5040,5044,5048,5052,5057,5061,5065,5069,5074,5079,5084,5088,5093],{"type":413,"tag":501,"props":5036,"children":5037},{"style":557},[5038],{"type":418,"value":5039},"    PrincipalId ",{"type":413,"tag":501,"props":5041,"children":5042},{"style":519},[5043],{"type":418,"value":736},{"type":413,"tag":501,"props":5045,"children":5046},{"style":557},[5047],{"type":418,"value":4275},{"type":413,"tag":501,"props":5049,"children":5050},{"style":519},[5051],{"type":418,"value":564},{"type":413,"tag":501,"props":5053,"children":5054},{"style":557},[5055],{"type":418,"value":5056},"Identity",{"type":413,"tag":501,"props":5058,"children":5059},{"style":519},[5060],{"type":418,"value":564},{"type":413,"tag":501,"props":5062,"children":5063},{"style":567},[5064],{"type":418,"value":1706},{"type":413,"tag":501,"props":5066,"children":5067},{"style":519},[5068],{"type":418,"value":575},{"type":413,"tag":501,"props":5070,"children":5071},{"style":508},[5072],{"type":418,"value":5073},"i",{"type":413,"tag":501,"props":5075,"children":5076},{"style":519},[5077],{"type":418,"value":5078}," =>",{"type":413,"tag":501,"props":5080,"children":5081},{"style":557},[5082],{"type":418,"value":5083}," i",{"type":413,"tag":501,"props":5085,"children":5086},{"style":519},[5087],{"type":418,"value":564},{"type":413,"tag":501,"props":5089,"children":5090},{"style":557},[5091],{"type":418,"value":5092},"PrincipalId",{"type":413,"tag":501,"props":5094,"children":5095},{"style":519},[5096],{"type":418,"value":3166},{"type":413,"tag":501,"props":5098,"children":5099},{"class":503,"line":649},[5100,5105,5109,5113,5117,5122],{"type":413,"tag":501,"props":5101,"children":5102},{"style":557},[5103],{"type":418,"value":5104},"    PrincipalType ",{"type":413,"tag":501,"props":5106,"children":5107},{"style":519},[5108],{"type":418,"value":736},{"type":413,"tag":501,"props":5110,"children":5111},{"style":557},[5112],{"type":418,"value":1129},{"type":413,"tag":501,"props":5114,"children":5115},{"style":519},[5116],{"type":418,"value":564},{"type":413,"tag":501,"props":5118,"children":5119},{"style":557},[5120],{"type":418,"value":5121},"ServicePrincipal",{"type":413,"tag":501,"props":5123,"children":5124},{"style":519},[5125],{"type":418,"value":745},{"type":413,"tag":501,"props":5127,"children":5128},{"class":503,"line":659},[5129,5134,5138,5142,5147,5151],{"type":413,"tag":501,"props":5130,"children":5131},{"style":557},[5132],{"type":418,"value":5133},"    RoleDefinitionId ",{"type":413,"tag":501,"props":5135,"children":5136},{"style":519},[5137],{"type":418,"value":736},{"type":413,"tag":501,"props":5139,"children":5140},{"style":519},[5141],{"type":418,"value":784},{"type":413,"tag":501,"props":5143,"children":5144},{"style":583},[5145],{"type":418,"value":5146},"/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b",{"type":413,"tag":501,"props":5148,"children":5149},{"style":519},[5150],{"type":418,"value":580},{"type":413,"tag":501,"props":5152,"children":5153},{"style":519},[5154],{"type":418,"value":745},{"type":413,"tag":501,"props":5156,"children":5157},{"class":503,"line":716},[5158,5163,5167,5171,5175],{"type":413,"tag":501,"props":5159,"children":5160},{"style":557},[5161],{"type":418,"value":5162},"    Scope ",{"type":413,"tag":501,"props":5164,"children":5165},{"style":519},[5166],{"type":418,"value":736},{"type":413,"tag":501,"props":5168,"children":5169},{"style":557},[5170],{"type":418,"value":3773},{"type":413,"tag":501,"props":5172,"children":5173},{"style":519},[5174],{"type":418,"value":564},{"type":413,"tag":501,"props":5176,"children":5177},{"style":557},[5178],{"type":418,"value":5179},"Id\n",{"type":413,"tag":501,"props":5181,"children":5182},{"class":503,"line":725},[5183],{"type":413,"tag":501,"props":5184,"children":5185},{"style":519},[5186],{"type":418,"value":803},{"type":413,"tag":466,"props":5188,"children":5189},{"icon":468},[5190],{"type":413,"tag":414,"props":5191,"children":5192},{},[5193],{"type":418,"value":5194},"Because the Azure provider is auto-generated from the Azure Resource Manager APIs, it is not always obvious to figure out what object and properties we should use to implement the infrastructure we want. Hopefully, because we are using a programming language in an IDE (C# in Visual Studio in my case), IntelliSense can help us.",{"type":413,"tag":414,"props":5196,"children":5197},{},[5198,5200,5205,5207,5212],{"type":418,"value":5199},"And that's just it, with this code the Function App will go well without needing the secret connection string of the storage in the AzureWebJobsStorage setting. Everything works fine thanks to the Managed Identity, the assignment of the correct role, and the setting ",{"type":413,"tag":443,"props":5201,"children":5203},{"className":5202},[],[5204],{"type":418,"value":3522},{"type":418,"value":5206},". One thing we could do is to remove the ",{"type":413,"tag":443,"props":5208,"children":5210},{"className":5209},[],[5211],{"type":418,"value":3522},{"type":418,"value":5213}," setting from the configuration to observe that without it, the Function App will not work properly: for instance, we would not be able to create function keys as a storage is needed to store them.",{"type":413,"tag":414,"props":5215,"children":5216},{},[5217,5219,5226],{"type":418,"value":5218},"You can find all this code on ",{"type":413,"tag":432,"props":5220,"children":5223},{"href":5221,"rel":5222},"https://github.com/TechWatching/FunctionAppWithoutSecretConnectionString",[436],[5224],{"type":418,"value":5225},"this GitHub repository",{"type":418,"value":5227}," if you want to test it by yourself. You will also find an HttpTrigger Azure Function created from the templates in Visual Studio that I only used to have something deployed on my Function App.",{"type":413,"tag":420,"props":5229,"children":5231},{"id":5230},"how-can-we-remove-the-azurewebjobsstorage-secret-setting-using-terraform",[5232],{"type":418,"value":5233},"How can we remove the AzureWebJobsStorage secret setting using Terraform?",{"type":413,"tag":414,"props":5235,"children":5236},{},[5237],{"type":418,"value":5238},"I am a big fan of Pulumi's approach to build and deploy infrastructure but as Terraform is pretty popular for doing Infrastructure as Code, I thought it might be a good idea to explain how to solve the same issue using Terraform instead of Pulumi.",{"type":413,"tag":414,"props":5240,"children":5241},{},[5242,5244,5251,5253,5259,5261,5267,5268,5274],{"type":418,"value":5243},"Well, in fact, you can't. 🤔 Currently there is no way to remove AzureWebJobsStorage secret using Terraform. Indeed as you can see in the ",{"type":413,"tag":432,"props":5245,"children":5248},{"href":5246,"rel":5247},"https://www.pulumi.com/blog/pulumiup-native-providers/",[436],[5249],{"type":418,"value":5250},"Terraform documentation of a Function App resource",{"type":418,"value":5252}," ",{"type":413,"tag":443,"props":5254,"children":5256},{"className":5255},[],[5257],{"type":418,"value":5258},"azurerm_function_app",{"type":418,"value":5260},", the AzureWebJobsStorage setting is automatically filled based on the ",{"type":413,"tag":443,"props":5262,"children":5264},{"className":5263},[],[5265],{"type":418,"value":5266},"storage_account_name",{"type":418,"value":1503},{"type":413,"tag":443,"props":5269,"children":5271},{"className":5270},[],[5272],{"type":418,"value":5273},"storage_account_access_key",{"type":418,"value":5275}," parameters which are required. So not only you can't use the Managed Identity access to storage as we did in Pulumi but also you can't use a key vault reference for the AzureWebJobsStorage setting (see the documentation screenshot below).",{"type":413,"tag":414,"props":5277,"children":5278},{},[5279],{"type":413,"tag":1580,"props":5280,"children":5284},{"alt":5281,"className":5282,"src":5283},"Azure RM provider for Terraform documentation about AzureWebJobsStorage.",[1584,1585],"/posts/images/functionsidentity_terraform_1.png",[],{"type":413,"tag":414,"props":5286,"children":5287},{},[5288,5290,5296],{"type":418,"value":5289},"The only possibility right now is to use an ARM template in your Terraform project thanks to the ",{"type":413,"tag":443,"props":5291,"children":5293},{"className":5292},[],[5294],{"type":418,"value":5295},"azurerm_resource_group_template_deployment",{"type":418,"value":5297}," resource but that defeats the whole point of using Terraform especially for a major resource like a Function App.",{"type":413,"tag":414,"props":5299,"children":5300},{},[5301],{"type":418,"value":5302},"In the GitHub repository of the Terraform provider for Azure RM there are 2 issues relative to this problem (do not hesitate to vote for them):",{"type":413,"tag":1523,"props":5304,"children":5305},{},[5306,5320],{"type":413,"tag":1527,"props":5307,"children":5308},{},[5309,5311,5318],{"type":418,"value":5310},"the ",{"type":413,"tag":432,"props":5312,"children":5315},{"href":5313,"rel":5314},"https://github.com/hashicorp/terraform-provider-azurerm/issues/8977",[436],[5316],{"type":418,"value":5317},"8977 issue",{"type":418,"value":5319}," that aims at supporting a KeyVault reference for the AzureWebJobsStorage setting",{"type":413,"tag":1527,"props":5321,"children":5322},{},[5323,5324,5331],{"type":418,"value":5310},{"type":413,"tag":432,"props":5325,"children":5328},{"href":5326,"rel":5327},"https://github.com/hashicorp/terraform-provider-azurerm/issues/13240",[436],[5329],{"type":418,"value":5330},"13240 issue",{"type":418,"value":5332}," that aims at supporting the Managed Identity access to storage",{"type":413,"tag":414,"props":5334,"children":5335},{},[5336],{"type":418,"value":5337},"I guess this will be implemented someday in Terraform provider for Azure RM, so that may not be a big deal but that clearly shows the limitations of Terraform providers.",{"type":413,"tag":466,"props":5339,"children":5340},{"icon":468},[5341],{"type":413,"tag":414,"props":5342,"children":5343},{},[5344],{"type":418,"value":5345},"Because Terraform provider for Azure RM is manually implemented using the Azure SDK, it does not match Azure APIs hence not all new resources and features are available (they have to be implemented in the provider as new features in Azure are released and it can take time). It's something that is not a problem with Pulumi Azure Native provider as the SDKs are generated automatically from the Azure API specifications which makes Pulumi Azure Native provider always up-to-date.",{"type":413,"tag":420,"props":5347,"children":5349},{"id":5348},"final-thoughts",[5350],{"type":418,"value":5351},"Final thoughts",{"type":413,"tag":414,"props":5353,"children":5354},{},[5355],{"type":418,"value":5356},"I hope that after reading this article if you are working on a Function App with an AzureWebJobsStorage setting you will take the time to replace it with an access to storage through the Managed Identity of your Function. One question you could ask me is why this is not the default behavior when creating a new Function App instead of using the AzureWebJobsStorage. And that would be an excellent question... for the Azure Functions team 😀.",{"type":413,"tag":414,"props":5358,"children":5359},{},[5360],{"type":418,"value":5361},"If you did not know Pulumi before reading this article, I hope it made you want to give it a try.\nHappy learning.",{"type":413,"tag":3363,"props":5363,"children":5364},{},[5365],{"type":418,"value":3367},{"title":401,"searchDepth":540,"depth":540,"links":5367},[5368,5369,5370,5371,5375,5376],{"id":3420,"depth":540,"text":3423},{"id":3460,"depth":540,"text":3463},{"id":3485,"depth":540,"text":3488},{"id":3557,"depth":540,"text":3560,"children":5372},[5373,5374],{"id":3576,"depth":598,"text":3579},{"id":3610,"depth":598,"text":3613},{"id":5230,"depth":540,"text":5233},{"id":5348,"depth":540,"text":5351},"content:1.posts:23.azure-functions-without-azurewebjobsstorage.md","1.posts/23.azure-functions-without-azurewebjobsstorage.md",{"_path":67,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":66,"description":5380,"lead":5381,"date":5382,"image":5383,"badge":5385,"tags":5387,"body":5388,"_type":3386,"_id":7793,"_source":3388,"_file":7794,"_extension":3390},"In Microsoft.Data.SqlClient v3.0.0, a new authentication mode Active Directory Default has been released. Let's see what this means when querying an Azure SQL Database from some C# code.","Talking about Active Directory Default authentication mode for SqlClient.","2021-06-22T00:00:00.000Z",{"src":5384},"/images/cloud-azure_1.jpg",{"label":5386},"Development",[252,299,302,228,225,236],{"type":410,"children":5389,"toc":7782},[5390,5409,5432,5437,5443,5463,5589,5600,5605,5628,5633,5639,5644,5649,5662,5674,5878,5917,5922,5935,5969,6047,6062,6068,6073,6079,6093,7077,7082,7117,7122,7136,7142,7156,7169,7671,7676,7734,7743,7759,7765,7778],{"type":413,"tag":414,"props":5391,"children":5392},{},[5393,5394,5399,5401,5407],{"type":418,"value":430},{"type":413,"tag":443,"props":5395,"children":5397},{"className":5396},[],[5398],{"type":418,"value":448},{"type":418,"value":5400}," v3.0.0, a new authentication mode ",{"type":413,"tag":443,"props":5402,"children":5404},{"className":5403},[],[5405],{"type":418,"value":5406},"Active Directory Default",{"type":418,"value":5408}," has been released. Let's see what this means when querying an Azure SQL Database from some C# code.",{"type":413,"tag":466,"props":5410,"children":5411},{"icon":468},[5412],{"type":413,"tag":414,"props":5413,"children":5414},{},[5415,5417,5422,5424,5430],{"type":418,"value":5416},"If you do not have heard about ",{"type":413,"tag":443,"props":5418,"children":5420},{"className":5419},[],[5421],{"type":418,"value":448},{"type":418,"value":5423},", it is the new data provider for Microsoft SQL Server and Azure SQL Database which supports both .NET Framework and .NET Core and replace the old ",{"type":413,"tag":443,"props":5425,"children":5427},{"className":5426},[],[5428],{"type":418,"value":5429},"System.Data.SqlClient",{"type":418,"value":5431}," components.",{"type":413,"tag":414,"props":5433,"children":5434},{},[5435],{"type":418,"value":5436},"But first, let's talk about how we used to do that before.",{"type":413,"tag":420,"props":5438,"children":5440},{"id":5439},"the-traditional-way-using-a-secret-connection-string",[5441],{"type":418,"value":5442},"The traditional way: using a secret connection string",{"type":413,"tag":414,"props":5444,"children":5445},{},[5446,5447,5453,5455,5461],{"type":418,"value":2679},{"type":413,"tag":443,"props":5448,"children":5450},{"className":5449},[],[5451],{"type":418,"value":5452},"traditional way",{"type":418,"value":5454}," to connect to an Azure SQL database from an application in C# is to provide to the ",{"type":413,"tag":443,"props":5456,"children":5458},{"className":5457},[],[5459],{"type":418,"value":5460},"SqlConnection",{"type":418,"value":5462}," constructor a connection string that contains a username and a password. The corresponding C# code is quite simple:",{"type":413,"tag":492,"props":5464,"children":5466},{"className":494,"code":5465,"language":326,"meta":401,"style":401},"var connectionString = \"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;User ID=globalSqlAdmin;Password=MySecretPassword;\");\n\nusing (var sqlConnection = new SqlConnection(connectionString));\nawait connection.OpenAsync();\n",[5467],{"type":413,"tag":443,"props":5468,"children":5469},{"__ignoreMap":401},[5470,5508,5515,5563],{"type":413,"tag":501,"props":5471,"children":5472},{"class":503,"line":504},[5473,5477,5482,5486,5490,5495,5499,5504],{"type":413,"tag":501,"props":5474,"children":5475},{"style":508},[5476],{"type":418,"value":511},{"type":413,"tag":501,"props":5478,"children":5479},{"style":508},[5480],{"type":418,"value":5481}," connectionString",{"type":413,"tag":501,"props":5483,"children":5484},{"style":519},[5485],{"type":418,"value":522},{"type":413,"tag":501,"props":5487,"children":5488},{"style":519},[5489],{"type":418,"value":784},{"type":413,"tag":501,"props":5491,"children":5492},{"style":583},[5493],{"type":418,"value":5494},"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;User ID=globalSqlAdmin;Password=MySecretPassword;",{"type":413,"tag":501,"props":5496,"children":5497},{"style":519},[5498],{"type":418,"value":580},{"type":413,"tag":501,"props":5500,"children":5501},{"style":557},[5502],{"type":418,"value":5503},")",{"type":413,"tag":501,"props":5505,"children":5506},{"style":519},[5507],{"type":418,"value":1430},{"type":413,"tag":501,"props":5509,"children":5510},{"class":503,"line":540},[5511],{"type":413,"tag":501,"props":5512,"children":5513},{"emptyLinePlaceholder":653},[5514],{"type":418,"value":656},{"type":413,"tag":501,"props":5516,"children":5517},{"class":503,"line":598},[5518,5523,5528,5532,5537,5541,5545,5550,5554,5559],{"type":413,"tag":501,"props":5519,"children":5520},{"style":1812},[5521],{"type":418,"value":5522},"using",{"type":413,"tag":501,"props":5524,"children":5525},{"style":519},[5526],{"type":418,"value":5527}," (",{"type":413,"tag":501,"props":5529,"children":5530},{"style":508},[5531],{"type":418,"value":511},{"type":413,"tag":501,"props":5533,"children":5534},{"style":508},[5535],{"type":418,"value":5536}," sqlConnection",{"type":413,"tag":501,"props":5538,"children":5539},{"style":519},[5540],{"type":418,"value":522},{"type":413,"tag":501,"props":5542,"children":5543},{"style":519},[5544],{"type":418,"value":527},{"type":413,"tag":501,"props":5546,"children":5547},{"style":508},[5548],{"type":418,"value":5549}," SqlConnection",{"type":413,"tag":501,"props":5551,"children":5552},{"style":519},[5553],{"type":418,"value":575},{"type":413,"tag":501,"props":5555,"children":5556},{"style":557},[5557],{"type":418,"value":5558},"connectionString",{"type":413,"tag":501,"props":5560,"children":5561},{"style":519},[5562],{"type":418,"value":2139},{"type":413,"tag":501,"props":5564,"children":5565},{"class":503,"line":649},[5566,5571,5576,5580,5585],{"type":413,"tag":501,"props":5567,"children":5568},{"style":519},[5569],{"type":418,"value":5570},"await",{"type":413,"tag":501,"props":5572,"children":5573},{"style":557},[5574],{"type":418,"value":5575}," connection",{"type":413,"tag":501,"props":5577,"children":5578},{"style":519},[5579],{"type":418,"value":564},{"type":413,"tag":501,"props":5581,"children":5582},{"style":567},[5583],{"type":418,"value":5584},"OpenAsync",{"type":413,"tag":501,"props":5586,"children":5587},{"style":519},[5588],{"type":418,"value":537},{"type":413,"tag":414,"props":5590,"children":5591},{},[5592,5594,5599],{"type":418,"value":5593},"In that case, the connection string is a secret we must secure and not just by putting it in some configuration location everyone can have access to, but by storing it in a secured place like ",{"type":413,"tag":443,"props":5595,"children":5597},{"className":5596},[],[5598],{"type":418,"value":260},{"type":418,"value":564},{"type":413,"tag":414,"props":5601,"children":5602},{},[5603],{"type":418,"value":5604},"However, even if you secure it appropriately, using a connection string with a username/password in it has some disadvantages:",{"type":413,"tag":1523,"props":5606,"children":5607},{},[5608,5613,5618,5623],{"type":413,"tag":1527,"props":5609,"children":5610},{},[5611],{"type":418,"value":5612},"you need to handle who has access to it (so who has access to the key vault)",{"type":413,"tag":1527,"props":5614,"children":5615},{},[5616],{"type":418,"value":5617},"every application or every developer could potentially use the same connection string so auditing is not very convenient (for instance identifying in the database logs which user has run a specific transaction)",{"type":413,"tag":1527,"props":5619,"children":5620},{},[5621],{"type":418,"value":5622},"you only control who has access to the connection string in the key vault, not what people do with it (share it by email, store it on their local computer, ...) so not who can access the database",{"type":413,"tag":1527,"props":5624,"children":5625},{},[5626],{"type":418,"value":5627},"you need to handle the rotation of the secret, in other words, change the username/password regularly (because you can revoke the access to someone to the database, if he had access to the connection string at some point in time it is not a secret for him anymore)",{"type":413,"tag":414,"props":5629,"children":5630},{},[5631],{"type":418,"value":5632},"For all these reasons, using a secret connection string to connect to an Azure SQL Database is not the right approach.",{"type":413,"tag":420,"props":5634,"children":5636},{"id":5635},"the-new-way-using-azure-active-directory-authentication",[5637],{"type":418,"value":5638},"The new way: using Azure Active Directory Authentication",{"type":413,"tag":414,"props":5640,"children":5641},{},[5642],{"type":418,"value":5643},"Instead of using a secret connection string to connect to a database, the idea is to use the Azure Active Directory authentication mechanism. Azure Active Directory is the location that contains all the identities of your users and your applications in your company. So you can manage directly which identity (user or application) have access to a database.",{"type":413,"tag":414,"props":5645,"children":5646},{},[5647],{"type":418,"value":5648},"Applications or users that want to query a database will authenticate against Azure AD to retrieve an access token that will allow them to access the database using a connection string without any username nor password.",{"type":413,"tag":414,"props":5650,"children":5651},{},[5652,5654,5661],{"type":418,"value":5653},"If you want to know more about the advantages of using Azure AD authentication for connecting to an Azure SQL Database you can have a look in the ",{"type":413,"tag":432,"props":5655,"children":5658},{"href":5656,"rel":5657},"https://docs.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-overview",[436],[5659],{"type":418,"value":5660},"official documentation",{"type":418,"value":564},{"type":413,"tag":414,"props":5663,"children":5664},{},[5665,5667,5672],{"type":418,"value":5666},"In the code we can remove the user id and password from the connection string but we have to retrieve an Azure AD access token and pass it to the ",{"type":413,"tag":443,"props":5668,"children":5670},{"className":5669},[],[5671],{"type":418,"value":5460},{"type":418,"value":5673}," instance:",{"type":413,"tag":492,"props":5675,"children":5677},{"className":494,"code":5676,"language":326,"meta":401,"style":401},"var accessToken = await new DefaultAzureCredential().GetTokenAsync(new TokenRequestContext(new string[] { \"https://database.windows.net//.default\" }));\nusing var connection = new SqlConnection(\"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;\")\n{\n    AccessToken = accessToken.Token\n};\nawait connection.OpenAsync();\n",[5678],{"type":413,"tag":443,"props":5679,"children":5680},{"__ignoreMap":401},[5681,5765,5815,5822,5847,5855],{"type":413,"tag":501,"props":5682,"children":5683},{"class":503,"line":504},[5684,5688,5693,5697,5702,5706,5711,5715,5720,5724,5729,5733,5738,5743,5747,5751,5756,5760],{"type":413,"tag":501,"props":5685,"children":5686},{"style":508},[5687],{"type":418,"value":511},{"type":413,"tag":501,"props":5689,"children":5690},{"style":508},[5691],{"type":418,"value":5692}," accessToken",{"type":413,"tag":501,"props":5694,"children":5695},{"style":519},[5696],{"type":418,"value":522},{"type":413,"tag":501,"props":5698,"children":5699},{"style":519},[5700],{"type":418,"value":5701}," await",{"type":413,"tag":501,"props":5703,"children":5704},{"style":519},[5705],{"type":418,"value":527},{"type":413,"tag":501,"props":5707,"children":5708},{"style":508},[5709],{"type":418,"value":5710}," DefaultAzureCredential",{"type":413,"tag":501,"props":5712,"children":5713},{"style":519},[5714],{"type":418,"value":2112},{"type":413,"tag":501,"props":5716,"children":5717},{"style":567},[5718],{"type":418,"value":5719},"GetTokenAsync",{"type":413,"tag":501,"props":5721,"children":5722},{"style":519},[5723],{"type":418,"value":2102},{"type":413,"tag":501,"props":5725,"children":5726},{"style":508},[5727],{"type":418,"value":5728}," TokenRequestContext",{"type":413,"tag":501,"props":5730,"children":5731},{"style":519},[5732],{"type":418,"value":2102},{"type":413,"tag":501,"props":5734,"children":5735},{"style":519},[5736],{"type":418,"value":5737}," string",{"type":413,"tag":501,"props":5739,"children":5740},{"style":519},[5741],{"type":418,"value":5742},"[]",{"type":413,"tag":501,"props":5744,"children":5745},{"style":519},[5746],{"type":418,"value":2512},{"type":413,"tag":501,"props":5748,"children":5749},{"style":519},[5750],{"type":418,"value":784},{"type":413,"tag":501,"props":5752,"children":5753},{"style":583},[5754],{"type":418,"value":5755},"https://database.windows.net//.default",{"type":413,"tag":501,"props":5757,"children":5758},{"style":519},[5759],{"type":418,"value":580},{"type":413,"tag":501,"props":5761,"children":5762},{"style":519},[5763],{"type":418,"value":5764}," }));\n",{"type":413,"tag":501,"props":5766,"children":5767},{"class":503,"line":540},[5768,5772,5777,5781,5785,5789,5793,5797,5801,5806,5810],{"type":413,"tag":501,"props":5769,"children":5770},{"style":1812},[5771],{"type":418,"value":5522},{"type":413,"tag":501,"props":5773,"children":5774},{"style":508},[5775],{"type":418,"value":5776}," var",{"type":413,"tag":501,"props":5778,"children":5779},{"style":508},[5780],{"type":418,"value":5575},{"type":413,"tag":501,"props":5782,"children":5783},{"style":519},[5784],{"type":418,"value":522},{"type":413,"tag":501,"props":5786,"children":5787},{"style":519},[5788],{"type":418,"value":527},{"type":413,"tag":501,"props":5790,"children":5791},{"style":508},[5792],{"type":418,"value":5549},{"type":413,"tag":501,"props":5794,"children":5795},{"style":519},[5796],{"type":418,"value":575},{"type":413,"tag":501,"props":5798,"children":5799},{"style":519},[5800],{"type":418,"value":580},{"type":413,"tag":501,"props":5802,"children":5803},{"style":583},[5804],{"type":418,"value":5805},"Server=server-testingmsi6499.database.windows.net; Database=database-testingmsi6499;",{"type":413,"tag":501,"props":5807,"children":5808},{"style":519},[5809],{"type":418,"value":580},{"type":413,"tag":501,"props":5811,"children":5812},{"style":519},[5813],{"type":418,"value":5814},")\n",{"type":413,"tag":501,"props":5816,"children":5817},{"class":503,"line":598},[5818],{"type":413,"tag":501,"props":5819,"children":5820},{"style":519},[5821],{"type":418,"value":722},{"type":413,"tag":501,"props":5823,"children":5824},{"class":503,"line":649},[5825,5830,5834,5838,5842],{"type":413,"tag":501,"props":5826,"children":5827},{"style":557},[5828],{"type":418,"value":5829},"    AccessToken ",{"type":413,"tag":501,"props":5831,"children":5832},{"style":519},[5833],{"type":418,"value":736},{"type":413,"tag":501,"props":5835,"children":5836},{"style":557},[5837],{"type":418,"value":5692},{"type":413,"tag":501,"props":5839,"children":5840},{"style":519},[5841],{"type":418,"value":564},{"type":413,"tag":501,"props":5843,"children":5844},{"style":557},[5845],{"type":418,"value":5846},"Token\n",{"type":413,"tag":501,"props":5848,"children":5849},{"class":503,"line":659},[5850],{"type":413,"tag":501,"props":5851,"children":5852},{"style":519},[5853],{"type":418,"value":5854},"};\n",{"type":413,"tag":501,"props":5856,"children":5857},{"class":503,"line":716},[5858,5862,5866,5870,5874],{"type":413,"tag":501,"props":5859,"children":5860},{"style":519},[5861],{"type":418,"value":5570},{"type":413,"tag":501,"props":5863,"children":5864},{"style":557},[5865],{"type":418,"value":5575},{"type":413,"tag":501,"props":5867,"children":5868},{"style":519},[5869],{"type":418,"value":564},{"type":413,"tag":501,"props":5871,"children":5872},{"style":567},[5873],{"type":418,"value":5584},{"type":413,"tag":501,"props":5875,"children":5876},{"style":519},[5877],{"type":418,"value":537},{"type":413,"tag":414,"props":5879,"children":5880},{},[5881,5883,5890,5892,5898,5900,5907,5909,5915],{"type":418,"value":5882},"The code is using the ",{"type":413,"tag":432,"props":5884,"children":5887},{"href":5885,"rel":5886},"https://docs.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme",[436],[5888],{"type":418,"value":5889},"Azure Identity library",{"type":418,"value":5891}," which as the documentation says \"",{"type":413,"tag":5893,"props":5894,"children":5895},"em",{},[5896],{"type":418,"value":5897},"provides Azure Active Directory token authentication support across the Azure SDK",{"type":418,"value":5899},"\". It is the recommended way to get an Azure token although you may have seen code that uses another library ",{"type":413,"tag":432,"props":5901,"children":5904},{"href":5902,"rel":5903},"https://www.nuget.org/packages/Microsoft.Azure.Services.AppAuthentication",[436],[5905],{"type":418,"value":5906},"Microsoft.Azure.Services.AppAuthentication",{"type":418,"value":5908}," to do the same thing. The class ",{"type":413,"tag":443,"props":5910,"children":5912},{"className":5911},[],[5913],{"type":418,"value":5914},"DefaultAzureCredential",{"type":418,"value":5916}," from Azure Identity library combines multiple authentication mechanisms (like Managed Identities, Visual Studio, Azure CLI ...) that will be tried in order to retrieve a token so it is a practical class that can handle most of the scenarios.",{"type":413,"tag":414,"props":5918,"children":5919},{},[5920],{"type":418,"value":5921},"Therefore, provided that you have granted access to your database to the user you are using locally (in Visual Studio, in vs code, or in Azure CLI) and to the managed identity of your application in Azure (App Service or Azure Function for instance) the same code will work both locally and in Azure.",{"type":413,"tag":420,"props":5923,"children":5925},{"id":5924},"here-comes-active-directory-default-authentication-mode",[5926,5928,5933],{"type":418,"value":5927},"Here comes ",{"type":413,"tag":443,"props":5929,"children":5931},{"className":5930},[],[5932],{"type":418,"value":5406},{"type":418,"value":5934}," authentication mode",{"type":413,"tag":414,"props":5936,"children":5937},{},[5938,5940,5945,5947,5952,5954,5960,5962,5967],{"type":418,"value":5939},"We have seen that using Azure Active Directory Authentication was a better solution than using a connection string with secrets in it to connect to a database. However, it involves manually retrieving an Azure AD token which makes the code a bit more complex to read. That is exactly why ",{"type":413,"tag":443,"props":5941,"children":5943},{"className":5942},[],[5944],{"type":418,"value":5406},{"type":418,"value":5946}," new authentication mode was introduced in ",{"type":413,"tag":443,"props":5948,"children":5950},{"className":5949},[],[5951],{"type":418,"value":448},{"type":418,"value":5953}," v3.0.0. Under the hood, ",{"type":413,"tag":443,"props":5955,"children":5957},{"className":5956},[],[5958],{"type":418,"value":5959},"SqlClient",{"type":418,"value":5961}," does the same thing that we were showing previously so we don't have to do it ourselves: just specifying the authentication mode to ",{"type":413,"tag":443,"props":5963,"children":5965},{"className":5964},[],[5966],{"type":418,"value":5406},{"type":418,"value":5968}," in the connection string is enough to make it work.",{"type":413,"tag":492,"props":5970,"children":5972},{"className":494,"code":5971,"language":326,"meta":401,"style":401},"using var connection = new SqlConnection(\"Server=server-testingmsi6499.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi6499;\");\nawait connection.OpenAsync();\n",[5973],{"type":413,"tag":443,"props":5974,"children":5975},{"__ignoreMap":401},[5976,6024],{"type":413,"tag":501,"props":5977,"children":5978},{"class":503,"line":504},[5979,5983,5987,5991,5995,5999,6003,6007,6011,6016,6020],{"type":413,"tag":501,"props":5980,"children":5981},{"style":1812},[5982],{"type":418,"value":5522},{"type":413,"tag":501,"props":5984,"children":5985},{"style":508},[5986],{"type":418,"value":5776},{"type":413,"tag":501,"props":5988,"children":5989},{"style":508},[5990],{"type":418,"value":5575},{"type":413,"tag":501,"props":5992,"children":5993},{"style":519},[5994],{"type":418,"value":522},{"type":413,"tag":501,"props":5996,"children":5997},{"style":519},[5998],{"type":418,"value":527},{"type":413,"tag":501,"props":6000,"children":6001},{"style":508},[6002],{"type":418,"value":5549},{"type":413,"tag":501,"props":6004,"children":6005},{"style":519},[6006],{"type":418,"value":575},{"type":413,"tag":501,"props":6008,"children":6009},{"style":519},[6010],{"type":418,"value":580},{"type":413,"tag":501,"props":6012,"children":6013},{"style":583},[6014],{"type":418,"value":6015},"Server=server-testingmsi6499.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi6499;",{"type":413,"tag":501,"props":6017,"children":6018},{"style":519},[6019],{"type":418,"value":580},{"type":413,"tag":501,"props":6021,"children":6022},{"style":519},[6023],{"type":418,"value":595},{"type":413,"tag":501,"props":6025,"children":6026},{"class":503,"line":540},[6027,6031,6035,6039,6043],{"type":413,"tag":501,"props":6028,"children":6029},{"style":519},[6030],{"type":418,"value":5570},{"type":413,"tag":501,"props":6032,"children":6033},{"style":557},[6034],{"type":418,"value":5575},{"type":413,"tag":501,"props":6036,"children":6037},{"style":519},[6038],{"type":418,"value":564},{"type":413,"tag":501,"props":6040,"children":6041},{"style":567},[6042],{"type":418,"value":5584},{"type":413,"tag":501,"props":6044,"children":6045},{"style":519},[6046],{"type":418,"value":537},{"type":413,"tag":466,"props":6048,"children":6049},{"icon":468},[6050],{"type":413,"tag":414,"props":6051,"children":6052},{},[6053,6055,6061],{"type":418,"value":6054},"There are other Azure Active Directory authentication methods available, you can find them in the documentation ",{"type":413,"tag":432,"props":6056,"children":6059},{"href":6057,"rel":6058},"https://docs.microsoft.com/en-us/sql/connect/ado-net/sql/azure-active-directory-authentication?view=sql-server-ver15#using-active-directory-password-authentication",[436],[6060],{"type":418,"value":3536},{"type":418,"value":564},{"type":413,"tag":420,"props":6063,"children":6065},{"id":6064},"a-complete-example",[6066],{"type":418,"value":6067},"A complete example",{"type":413,"tag":414,"props":6069,"children":6070},{},[6071],{"type":418,"value":6072},"Enough theory, what if you want to quickly test this by yourself?",{"type":413,"tag":1556,"props":6074,"children":6076},{"id":6075},"a-bit-of-azure-cli-to-initialize-the-database",[6077],{"type":418,"value":6078},"A bit of Azure CLI to initialize the database",{"type":413,"tag":414,"props":6080,"children":6081},{},[6082,6084,6091],{"type":418,"value":6083},"I took an ",{"type":413,"tag":432,"props":6085,"children":6088},{"href":6086,"rel":6087},"https://docs.microsoft.com/en-us/azure/azure-sql/database/scripts/create-and-configure-database-cli",[436],[6089],{"type":418,"value":6090},"Azure CLI sample script",{"type":418,"value":6092}," from Microsoft and modify it a little to configure a database with all that is necessary to use Azure Active Directory to connect my user to it.",{"type":413,"tag":492,"props":6094,"children":6098},{"className":6095,"code":6096,"language":6097,"meta":401,"style":401},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#!/bin/bash\nlocation=\"West Europe\" # to change with your preferred location\nrandomIdentifier=testingmsi${RANDOM:0:5}\n\nresourceGroup=\"resource-$randomIdentifier\"\nserver=\"server-$randomIdentifier\"\ndatabase=\"database-$randomIdentifier\"\n\nlogin=\"globalSqlAdmin\"\npassword=\"P@ssw0rdToChange!\" # to change to have a more secured password\n\n# Retrieve your public IP.\n# Replace by your local machine IP if you are executing this script from cloud shell.\nstartIP=$(dig +short myip.opendns.com @resolver1.opendns.com)\nendIP=$startIP\n\n# Retrieve your current logged-in user to be used as SQL server admin. \n# Change with another user id if you want another user to be an admin.\nazureaduser=$(az ad signed-in-user show --query \"objectId\" -o tsv)\n\necho \"Creating $resourceGroup...\"\naz group create --name $resourceGroup --location \"$location\"\n\necho \"Creating $server in $location...\"\naz sql server create --name $server --resource-group $resourceGroup --location \"$location\" --admin-user $login --admin-password $password\n\necho \"Configuring firewall...\"\naz sql server firewall-rule create --resource-group $resourceGroup --server $server -n AllowYourIp --start-ip-address $startIP --end-ip-address $endIP\n\necho \"Creating $database on $server...\"\naz sql db create --resource-group $resourceGroup --server $server --name $database --sample-name AdventureWorksLT --service-objective Basic --zone-redundant false\n\necho \"Creating AD admin in sql server...\"\naz sql server ad-admin create --resource-group $resourceGroup --server-name $server --display-name ADMIN --object-id $azureaduser\n\necho \"Database connection string to use: \\\"Server=$server.database.windows.net; Authentication=Active Directory Default; Database=$database;\\\"\"\n","bash",[6099],{"type":413,"tag":443,"props":6100,"children":6101},{"__ignoreMap":401},[6102,6110,6140,6190,6197,6226,6255,6283,6290,6315,6345,6352,6360,6368,6405,6422,6429,6437,6445,6509,6516,6547,6592,6599,6636,6711,6718,6738,6810,6817,6854,6930,6937,6957,7018,7025],{"type":413,"tag":501,"props":6103,"children":6104},{"class":503,"line":504},[6105],{"type":413,"tag":501,"props":6106,"children":6107},{"style":1766},[6108],{"type":418,"value":6109},"#!/bin/bash\n",{"type":413,"tag":501,"props":6111,"children":6112},{"class":503,"line":540},[6113,6118,6122,6126,6131,6135],{"type":413,"tag":501,"props":6114,"children":6115},{"style":557},[6116],{"type":418,"value":6117},"location",{"type":413,"tag":501,"props":6119,"children":6120},{"style":519},[6121],{"type":418,"value":736},{"type":413,"tag":501,"props":6123,"children":6124},{"style":519},[6125],{"type":418,"value":580},{"type":413,"tag":501,"props":6127,"children":6128},{"style":583},[6129],{"type":418,"value":6130},"West Europe",{"type":413,"tag":501,"props":6132,"children":6133},{"style":519},[6134],{"type":418,"value":580},{"type":413,"tag":501,"props":6136,"children":6137},{"style":1766},[6138],{"type":418,"value":6139}," # to change with your preferred location\n",{"type":413,"tag":501,"props":6141,"children":6142},{"class":503,"line":598},[6143,6148,6152,6157,6162,6167,6172,6177,6181,6186],{"type":413,"tag":501,"props":6144,"children":6145},{"style":557},[6146],{"type":418,"value":6147},"randomIdentifier",{"type":413,"tag":501,"props":6149,"children":6150},{"style":519},[6151],{"type":418,"value":736},{"type":413,"tag":501,"props":6153,"children":6154},{"style":583},[6155],{"type":418,"value":6156},"testingmsi",{"type":413,"tag":501,"props":6158,"children":6159},{"style":519},[6160],{"type":418,"value":6161},"${",{"type":413,"tag":501,"props":6163,"children":6164},{"style":557},[6165],{"type":418,"value":6166},"RANDOM",{"type":413,"tag":501,"props":6168,"children":6169},{"style":519},[6170],{"type":418,"value":6171},":",{"type":413,"tag":501,"props":6173,"children":6174},{"style":557},[6175],{"type":418,"value":6176},"0",{"type":413,"tag":501,"props":6178,"children":6179},{"style":519},[6180],{"type":418,"value":6171},{"type":413,"tag":501,"props":6182,"children":6183},{"style":557},[6184],{"type":418,"value":6185},"5",{"type":413,"tag":501,"props":6187,"children":6188},{"style":519},[6189],{"type":418,"value":2530},{"type":413,"tag":501,"props":6191,"children":6192},{"class":503,"line":649},[6193],{"type":413,"tag":501,"props":6194,"children":6195},{"emptyLinePlaceholder":653},[6196],{"type":418,"value":656},{"type":413,"tag":501,"props":6198,"children":6199},{"class":503,"line":659},[6200,6204,6208,6212,6217,6222],{"type":413,"tag":501,"props":6201,"children":6202},{"style":557},[6203],{"type":418,"value":3752},{"type":413,"tag":501,"props":6205,"children":6206},{"style":519},[6207],{"type":418,"value":736},{"type":413,"tag":501,"props":6209,"children":6210},{"style":519},[6211],{"type":418,"value":580},{"type":413,"tag":501,"props":6213,"children":6214},{"style":583},[6215],{"type":418,"value":6216},"resource-",{"type":413,"tag":501,"props":6218,"children":6219},{"style":557},[6220],{"type":418,"value":6221},"$randomIdentifier",{"type":413,"tag":501,"props":6223,"children":6224},{"style":519},[6225],{"type":418,"value":794},{"type":413,"tag":501,"props":6227,"children":6228},{"class":503,"line":716},[6229,6234,6238,6242,6247,6251],{"type":413,"tag":501,"props":6230,"children":6231},{"style":557},[6232],{"type":418,"value":6233},"server",{"type":413,"tag":501,"props":6235,"children":6236},{"style":519},[6237],{"type":418,"value":736},{"type":413,"tag":501,"props":6239,"children":6240},{"style":519},[6241],{"type":418,"value":580},{"type":413,"tag":501,"props":6243,"children":6244},{"style":583},[6245],{"type":418,"value":6246},"server-",{"type":413,"tag":501,"props":6248,"children":6249},{"style":557},[6250],{"type":418,"value":6221},{"type":413,"tag":501,"props":6252,"children":6253},{"style":519},[6254],{"type":418,"value":794},{"type":413,"tag":501,"props":6256,"children":6257},{"class":503,"line":725},[6258,6262,6266,6270,6275,6279],{"type":413,"tag":501,"props":6259,"children":6260},{"style":557},[6261],{"type":418,"value":1723},{"type":413,"tag":501,"props":6263,"children":6264},{"style":519},[6265],{"type":418,"value":736},{"type":413,"tag":501,"props":6267,"children":6268},{"style":519},[6269],{"type":418,"value":580},{"type":413,"tag":501,"props":6271,"children":6272},{"style":583},[6273],{"type":418,"value":6274},"database-",{"type":413,"tag":501,"props":6276,"children":6277},{"style":557},[6278],{"type":418,"value":6221},{"type":413,"tag":501,"props":6280,"children":6281},{"style":519},[6282],{"type":418,"value":794},{"type":413,"tag":501,"props":6284,"children":6285},{"class":503,"line":748},[6286],{"type":413,"tag":501,"props":6287,"children":6288},{"emptyLinePlaceholder":653},[6289],{"type":418,"value":656},{"type":413,"tag":501,"props":6291,"children":6292},{"class":503,"line":769},[6293,6298,6302,6306,6311],{"type":413,"tag":501,"props":6294,"children":6295},{"style":557},[6296],{"type":418,"value":6297},"login",{"type":413,"tag":501,"props":6299,"children":6300},{"style":519},[6301],{"type":418,"value":736},{"type":413,"tag":501,"props":6303,"children":6304},{"style":519},[6305],{"type":418,"value":580},{"type":413,"tag":501,"props":6307,"children":6308},{"style":583},[6309],{"type":418,"value":6310},"globalSqlAdmin",{"type":413,"tag":501,"props":6312,"children":6313},{"style":519},[6314],{"type":418,"value":794},{"type":413,"tag":501,"props":6316,"children":6317},{"class":503,"line":797},[6318,6323,6327,6331,6336,6340],{"type":413,"tag":501,"props":6319,"children":6320},{"style":557},[6321],{"type":418,"value":6322},"password",{"type":413,"tag":501,"props":6324,"children":6325},{"style":519},[6326],{"type":418,"value":736},{"type":413,"tag":501,"props":6328,"children":6329},{"style":519},[6330],{"type":418,"value":580},{"type":413,"tag":501,"props":6332,"children":6333},{"style":583},[6334],{"type":418,"value":6335},"P@ssw0rdToChange!",{"type":413,"tag":501,"props":6337,"children":6338},{"style":519},[6339],{"type":418,"value":580},{"type":413,"tag":501,"props":6341,"children":6342},{"style":1766},[6343],{"type":418,"value":6344}," # to change to have a more secured password\n",{"type":413,"tag":501,"props":6346,"children":6347},{"class":503,"line":1145},[6348],{"type":413,"tag":501,"props":6349,"children":6350},{"emptyLinePlaceholder":653},[6351],{"type":418,"value":656},{"type":413,"tag":501,"props":6353,"children":6354},{"class":503,"line":1154},[6355],{"type":413,"tag":501,"props":6356,"children":6357},{"style":1766},[6358],{"type":418,"value":6359},"# Retrieve your public IP.\n",{"type":413,"tag":501,"props":6361,"children":6362},{"class":503,"line":4568},[6363],{"type":413,"tag":501,"props":6364,"children":6365},{"style":1766},[6366],{"type":418,"value":6367},"# Replace by your local machine IP if you are executing this script from cloud shell.\n",{"type":413,"tag":501,"props":6369,"children":6370},{"class":503,"line":4577},[6371,6376,6381,6386,6391,6396,6401],{"type":413,"tag":501,"props":6372,"children":6373},{"style":557},[6374],{"type":418,"value":6375},"startIP",{"type":413,"tag":501,"props":6377,"children":6378},{"style":519},[6379],{"type":418,"value":6380},"=$(",{"type":413,"tag":501,"props":6382,"children":6383},{"style":508},[6384],{"type":418,"value":6385},"dig",{"type":413,"tag":501,"props":6387,"children":6388},{"style":583},[6389],{"type":418,"value":6390}," +short",{"type":413,"tag":501,"props":6392,"children":6393},{"style":583},[6394],{"type":418,"value":6395}," myip.opendns.com",{"type":413,"tag":501,"props":6397,"children":6398},{"style":583},[6399],{"type":418,"value":6400}," @resolver1.opendns.com",{"type":413,"tag":501,"props":6402,"children":6403},{"style":519},[6404],{"type":418,"value":5814},{"type":413,"tag":501,"props":6406,"children":6407},{"class":503,"line":4591},[6408,6413,6417],{"type":413,"tag":501,"props":6409,"children":6410},{"style":557},[6411],{"type":418,"value":6412},"endIP",{"type":413,"tag":501,"props":6414,"children":6415},{"style":519},[6416],{"type":418,"value":736},{"type":413,"tag":501,"props":6418,"children":6419},{"style":557},[6420],{"type":418,"value":6421},"$startIP\n",{"type":413,"tag":501,"props":6423,"children":6424},{"class":503,"line":4600},[6425],{"type":413,"tag":501,"props":6426,"children":6427},{"emptyLinePlaceholder":653},[6428],{"type":418,"value":656},{"type":413,"tag":501,"props":6430,"children":6431},{"class":503,"line":4630},[6432],{"type":413,"tag":501,"props":6433,"children":6434},{"style":1766},[6435],{"type":418,"value":6436},"# Retrieve your current logged-in user to be used as SQL server admin. \n",{"type":413,"tag":501,"props":6438,"children":6439},{"class":503,"line":4660},[6440],{"type":413,"tag":501,"props":6441,"children":6442},{"style":1766},[6443],{"type":418,"value":6444},"# Change with another user id if you want another user to be an admin.\n",{"type":413,"tag":501,"props":6446,"children":6447},{"class":503,"line":4669},[6448,6453,6457,6462,6467,6472,6477,6482,6486,6491,6495,6500,6505],{"type":413,"tag":501,"props":6449,"children":6450},{"style":557},[6451],{"type":418,"value":6452},"azureaduser",{"type":413,"tag":501,"props":6454,"children":6455},{"style":519},[6456],{"type":418,"value":6380},{"type":413,"tag":501,"props":6458,"children":6459},{"style":508},[6460],{"type":418,"value":6461},"az",{"type":413,"tag":501,"props":6463,"children":6464},{"style":583},[6465],{"type":418,"value":6466}," ad",{"type":413,"tag":501,"props":6468,"children":6469},{"style":583},[6470],{"type":418,"value":6471}," signed-in-user",{"type":413,"tag":501,"props":6473,"children":6474},{"style":583},[6475],{"type":418,"value":6476}," show",{"type":413,"tag":501,"props":6478,"children":6479},{"style":583},[6480],{"type":418,"value":6481}," --query",{"type":413,"tag":501,"props":6483,"children":6484},{"style":519},[6485],{"type":418,"value":784},{"type":413,"tag":501,"props":6487,"children":6488},{"style":583},[6489],{"type":418,"value":6490},"objectId",{"type":413,"tag":501,"props":6492,"children":6493},{"style":519},[6494],{"type":418,"value":580},{"type":413,"tag":501,"props":6496,"children":6497},{"style":583},[6498],{"type":418,"value":6499}," -o",{"type":413,"tag":501,"props":6501,"children":6502},{"style":583},[6503],{"type":418,"value":6504}," tsv",{"type":413,"tag":501,"props":6506,"children":6507},{"style":519},[6508],{"type":418,"value":5814},{"type":413,"tag":501,"props":6510,"children":6511},{"class":503,"line":4681},[6512],{"type":413,"tag":501,"props":6513,"children":6514},{"emptyLinePlaceholder":653},[6515],{"type":418,"value":656},{"type":413,"tag":501,"props":6517,"children":6518},{"class":503,"line":4689},[6519,6524,6528,6533,6538,6543],{"type":413,"tag":501,"props":6520,"children":6521},{"style":567},[6522],{"type":418,"value":6523},"echo",{"type":413,"tag":501,"props":6525,"children":6526},{"style":519},[6527],{"type":418,"value":784},{"type":413,"tag":501,"props":6529,"children":6530},{"style":583},[6531],{"type":418,"value":6532},"Creating ",{"type":413,"tag":501,"props":6534,"children":6535},{"style":557},[6536],{"type":418,"value":6537},"$resourceGroup",{"type":413,"tag":501,"props":6539,"children":6540},{"style":583},[6541],{"type":418,"value":6542},"...",{"type":413,"tag":501,"props":6544,"children":6545},{"style":519},[6546],{"type":418,"value":794},{"type":413,"tag":501,"props":6548,"children":6549},{"class":503,"line":4718},[6550,6554,6559,6564,6569,6574,6579,6583,6588],{"type":413,"tag":501,"props":6551,"children":6552},{"style":508},[6553],{"type":418,"value":6461},{"type":413,"tag":501,"props":6555,"children":6556},{"style":583},[6557],{"type":418,"value":6558}," group",{"type":413,"tag":501,"props":6560,"children":6561},{"style":583},[6562],{"type":418,"value":6563}," create",{"type":413,"tag":501,"props":6565,"children":6566},{"style":583},[6567],{"type":418,"value":6568}," --name",{"type":413,"tag":501,"props":6570,"children":6571},{"style":557},[6572],{"type":418,"value":6573}," $resourceGroup ",{"type":413,"tag":501,"props":6575,"children":6576},{"style":583},[6577],{"type":418,"value":6578},"--location",{"type":413,"tag":501,"props":6580,"children":6581},{"style":519},[6582],{"type":418,"value":784},{"type":413,"tag":501,"props":6584,"children":6585},{"style":557},[6586],{"type":418,"value":6587},"$location",{"type":413,"tag":501,"props":6589,"children":6590},{"style":519},[6591],{"type":418,"value":794},{"type":413,"tag":501,"props":6593,"children":6594},{"class":503,"line":4746},[6595],{"type":413,"tag":501,"props":6596,"children":6597},{"emptyLinePlaceholder":653},[6598],{"type":418,"value":656},{"type":413,"tag":501,"props":6600,"children":6601},{"class":503,"line":4754},[6602,6606,6610,6614,6619,6624,6628,6632],{"type":413,"tag":501,"props":6603,"children":6604},{"style":567},[6605],{"type":418,"value":6523},{"type":413,"tag":501,"props":6607,"children":6608},{"style":519},[6609],{"type":418,"value":784},{"type":413,"tag":501,"props":6611,"children":6612},{"style":583},[6613],{"type":418,"value":6532},{"type":413,"tag":501,"props":6615,"children":6616},{"style":557},[6617],{"type":418,"value":6618},"$server",{"type":413,"tag":501,"props":6620,"children":6621},{"style":583},[6622],{"type":418,"value":6623}," in ",{"type":413,"tag":501,"props":6625,"children":6626},{"style":557},[6627],{"type":418,"value":6587},{"type":413,"tag":501,"props":6629,"children":6630},{"style":583},[6631],{"type":418,"value":6542},{"type":413,"tag":501,"props":6633,"children":6634},{"style":519},[6635],{"type":418,"value":794},{"type":413,"tag":501,"props":6637,"children":6638},{"class":503,"line":4766},[6639,6643,6648,6653,6657,6661,6666,6671,6675,6679,6683,6687,6691,6696,6701,6706],{"type":413,"tag":501,"props":6640,"children":6641},{"style":508},[6642],{"type":418,"value":6461},{"type":413,"tag":501,"props":6644,"children":6645},{"style":583},[6646],{"type":418,"value":6647}," sql",{"type":413,"tag":501,"props":6649,"children":6650},{"style":583},[6651],{"type":418,"value":6652}," server",{"type":413,"tag":501,"props":6654,"children":6655},{"style":583},[6656],{"type":418,"value":6563},{"type":413,"tag":501,"props":6658,"children":6659},{"style":583},[6660],{"type":418,"value":6568},{"type":413,"tag":501,"props":6662,"children":6663},{"style":557},[6664],{"type":418,"value":6665}," $server ",{"type":413,"tag":501,"props":6667,"children":6668},{"style":583},[6669],{"type":418,"value":6670},"--resource-group",{"type":413,"tag":501,"props":6672,"children":6673},{"style":557},[6674],{"type":418,"value":6573},{"type":413,"tag":501,"props":6676,"children":6677},{"style":583},[6678],{"type":418,"value":6578},{"type":413,"tag":501,"props":6680,"children":6681},{"style":519},[6682],{"type":418,"value":784},{"type":413,"tag":501,"props":6684,"children":6685},{"style":557},[6686],{"type":418,"value":6587},{"type":413,"tag":501,"props":6688,"children":6689},{"style":519},[6690],{"type":418,"value":580},{"type":413,"tag":501,"props":6692,"children":6693},{"style":583},[6694],{"type":418,"value":6695}," --admin-user",{"type":413,"tag":501,"props":6697,"children":6698},{"style":557},[6699],{"type":418,"value":6700}," $login ",{"type":413,"tag":501,"props":6702,"children":6703},{"style":583},[6704],{"type":418,"value":6705},"--admin-password",{"type":413,"tag":501,"props":6707,"children":6708},{"style":557},[6709],{"type":418,"value":6710}," $password\n",{"type":413,"tag":501,"props":6712,"children":6713},{"class":503,"line":4774},[6714],{"type":413,"tag":501,"props":6715,"children":6716},{"emptyLinePlaceholder":653},[6717],{"type":418,"value":656},{"type":413,"tag":501,"props":6719,"children":6720},{"class":503,"line":4803},[6721,6725,6729,6734],{"type":413,"tag":501,"props":6722,"children":6723},{"style":567},[6724],{"type":418,"value":6523},{"type":413,"tag":501,"props":6726,"children":6727},{"style":519},[6728],{"type":418,"value":784},{"type":413,"tag":501,"props":6730,"children":6731},{"style":583},[6732],{"type":418,"value":6733},"Configuring firewall...",{"type":413,"tag":501,"props":6735,"children":6736},{"style":519},[6737],{"type":418,"value":794},{"type":413,"tag":501,"props":6739,"children":6740},{"class":503,"line":4828},[6741,6745,6749,6753,6758,6762,6767,6771,6776,6780,6785,6790,6795,6800,6805],{"type":413,"tag":501,"props":6742,"children":6743},{"style":508},[6744],{"type":418,"value":6461},{"type":413,"tag":501,"props":6746,"children":6747},{"style":583},[6748],{"type":418,"value":6647},{"type":413,"tag":501,"props":6750,"children":6751},{"style":583},[6752],{"type":418,"value":6652},{"type":413,"tag":501,"props":6754,"children":6755},{"style":583},[6756],{"type":418,"value":6757}," firewall-rule",{"type":413,"tag":501,"props":6759,"children":6760},{"style":583},[6761],{"type":418,"value":6563},{"type":413,"tag":501,"props":6763,"children":6764},{"style":583},[6765],{"type":418,"value":6766}," --resource-group",{"type":413,"tag":501,"props":6768,"children":6769},{"style":557},[6770],{"type":418,"value":6573},{"type":413,"tag":501,"props":6772,"children":6773},{"style":583},[6774],{"type":418,"value":6775},"--server",{"type":413,"tag":501,"props":6777,"children":6778},{"style":557},[6779],{"type":418,"value":6665},{"type":413,"tag":501,"props":6781,"children":6782},{"style":583},[6783],{"type":418,"value":6784},"-n",{"type":413,"tag":501,"props":6786,"children":6787},{"style":583},[6788],{"type":418,"value":6789}," AllowYourIp",{"type":413,"tag":501,"props":6791,"children":6792},{"style":583},[6793],{"type":418,"value":6794}," --start-ip-address",{"type":413,"tag":501,"props":6796,"children":6797},{"style":557},[6798],{"type":418,"value":6799}," $startIP ",{"type":413,"tag":501,"props":6801,"children":6802},{"style":583},[6803],{"type":418,"value":6804},"--end-ip-address",{"type":413,"tag":501,"props":6806,"children":6807},{"style":557},[6808],{"type":418,"value":6809}," $endIP\n",{"type":413,"tag":501,"props":6811,"children":6812},{"class":503,"line":4836},[6813],{"type":413,"tag":501,"props":6814,"children":6815},{"emptyLinePlaceholder":653},[6816],{"type":418,"value":656},{"type":413,"tag":501,"props":6818,"children":6819},{"class":503,"line":4848},[6820,6824,6828,6832,6837,6842,6846,6850],{"type":413,"tag":501,"props":6821,"children":6822},{"style":567},[6823],{"type":418,"value":6523},{"type":413,"tag":501,"props":6825,"children":6826},{"style":519},[6827],{"type":418,"value":784},{"type":413,"tag":501,"props":6829,"children":6830},{"style":583},[6831],{"type":418,"value":6532},{"type":413,"tag":501,"props":6833,"children":6834},{"style":557},[6835],{"type":418,"value":6836},"$database",{"type":413,"tag":501,"props":6838,"children":6839},{"style":583},[6840],{"type":418,"value":6841}," on ",{"type":413,"tag":501,"props":6843,"children":6844},{"style":557},[6845],{"type":418,"value":6618},{"type":413,"tag":501,"props":6847,"children":6848},{"style":583},[6849],{"type":418,"value":6542},{"type":413,"tag":501,"props":6851,"children":6852},{"style":519},[6853],{"type":418,"value":794},{"type":413,"tag":501,"props":6855,"children":6856},{"class":503,"line":4856},[6857,6861,6865,6870,6874,6878,6882,6886,6890,6895,6900,6905,6910,6915,6920,6925],{"type":413,"tag":501,"props":6858,"children":6859},{"style":508},[6860],{"type":418,"value":6461},{"type":413,"tag":501,"props":6862,"children":6863},{"style":583},[6864],{"type":418,"value":6647},{"type":413,"tag":501,"props":6866,"children":6867},{"style":583},[6868],{"type":418,"value":6869}," db",{"type":413,"tag":501,"props":6871,"children":6872},{"style":583},[6873],{"type":418,"value":6563},{"type":413,"tag":501,"props":6875,"children":6876},{"style":583},[6877],{"type":418,"value":6766},{"type":413,"tag":501,"props":6879,"children":6880},{"style":557},[6881],{"type":418,"value":6573},{"type":413,"tag":501,"props":6883,"children":6884},{"style":583},[6885],{"type":418,"value":6775},{"type":413,"tag":501,"props":6887,"children":6888},{"style":557},[6889],{"type":418,"value":6665},{"type":413,"tag":501,"props":6891,"children":6892},{"style":583},[6893],{"type":418,"value":6894},"--name",{"type":413,"tag":501,"props":6896,"children":6897},{"style":557},[6898],{"type":418,"value":6899}," $database ",{"type":413,"tag":501,"props":6901,"children":6902},{"style":583},[6903],{"type":418,"value":6904},"--sample-name",{"type":413,"tag":501,"props":6906,"children":6907},{"style":583},[6908],{"type":418,"value":6909}," AdventureWorksLT",{"type":413,"tag":501,"props":6911,"children":6912},{"style":583},[6913],{"type":418,"value":6914}," --service-objective",{"type":413,"tag":501,"props":6916,"children":6917},{"style":583},[6918],{"type":418,"value":6919}," Basic",{"type":413,"tag":501,"props":6921,"children":6922},{"style":583},[6923],{"type":418,"value":6924}," --zone-redundant",{"type":413,"tag":501,"props":6926,"children":6927},{"style":519},[6928],{"type":418,"value":6929}," false\n",{"type":413,"tag":501,"props":6931,"children":6932},{"class":503,"line":4884},[6933],{"type":413,"tag":501,"props":6934,"children":6935},{"emptyLinePlaceholder":653},[6936],{"type":418,"value":656},{"type":413,"tag":501,"props":6938,"children":6939},{"class":503,"line":4909},[6940,6944,6948,6953],{"type":413,"tag":501,"props":6941,"children":6942},{"style":567},[6943],{"type":418,"value":6523},{"type":413,"tag":501,"props":6945,"children":6946},{"style":519},[6947],{"type":418,"value":784},{"type":413,"tag":501,"props":6949,"children":6950},{"style":583},[6951],{"type":418,"value":6952},"Creating AD admin in sql server...",{"type":413,"tag":501,"props":6954,"children":6955},{"style":519},[6956],{"type":418,"value":794},{"type":413,"tag":501,"props":6958,"children":6959},{"class":503,"line":4918},[6960,6964,6968,6972,6977,6981,6985,6989,6994,6998,7003,7008,7013],{"type":413,"tag":501,"props":6961,"children":6962},{"style":508},[6963],{"type":418,"value":6461},{"type":413,"tag":501,"props":6965,"children":6966},{"style":583},[6967],{"type":418,"value":6647},{"type":413,"tag":501,"props":6969,"children":6970},{"style":583},[6971],{"type":418,"value":6652},{"type":413,"tag":501,"props":6973,"children":6974},{"style":583},[6975],{"type":418,"value":6976}," ad-admin",{"type":413,"tag":501,"props":6978,"children":6979},{"style":583},[6980],{"type":418,"value":6563},{"type":413,"tag":501,"props":6982,"children":6983},{"style":583},[6984],{"type":418,"value":6766},{"type":413,"tag":501,"props":6986,"children":6987},{"style":557},[6988],{"type":418,"value":6573},{"type":413,"tag":501,"props":6990,"children":6991},{"style":583},[6992],{"type":418,"value":6993},"--server-name",{"type":413,"tag":501,"props":6995,"children":6996},{"style":557},[6997],{"type":418,"value":6665},{"type":413,"tag":501,"props":6999,"children":7000},{"style":583},[7001],{"type":418,"value":7002},"--display-name",{"type":413,"tag":501,"props":7004,"children":7005},{"style":583},[7006],{"type":418,"value":7007}," ADMIN",{"type":413,"tag":501,"props":7009,"children":7010},{"style":583},[7011],{"type":418,"value":7012}," --object-id",{"type":413,"tag":501,"props":7014,"children":7015},{"style":557},[7016],{"type":418,"value":7017}," $azureaduser\n",{"type":413,"tag":501,"props":7019,"children":7020},{"class":503,"line":4927},[7021],{"type":413,"tag":501,"props":7022,"children":7023},{"emptyLinePlaceholder":653},[7024],{"type":418,"value":656},{"type":413,"tag":501,"props":7026,"children":7027},{"class":503,"line":4935},[7028,7032,7036,7041,7046,7051,7055,7060,7064,7069,7073],{"type":413,"tag":501,"props":7029,"children":7030},{"style":567},[7031],{"type":418,"value":6523},{"type":413,"tag":501,"props":7033,"children":7034},{"style":519},[7035],{"type":418,"value":784},{"type":413,"tag":501,"props":7037,"children":7038},{"style":583},[7039],{"type":418,"value":7040},"Database connection string to use: ",{"type":413,"tag":501,"props":7042,"children":7043},{"style":557},[7044],{"type":418,"value":7045},"\\\"",{"type":413,"tag":501,"props":7047,"children":7048},{"style":583},[7049],{"type":418,"value":7050},"Server=",{"type":413,"tag":501,"props":7052,"children":7053},{"style":557},[7054],{"type":418,"value":6618},{"type":413,"tag":501,"props":7056,"children":7057},{"style":583},[7058],{"type":418,"value":7059},".database.windows.net; Authentication=Active Directory Default; Database=",{"type":413,"tag":501,"props":7061,"children":7062},{"style":557},[7063],{"type":418,"value":6836},{"type":413,"tag":501,"props":7065,"children":7066},{"style":583},[7067],{"type":418,"value":7068},";",{"type":413,"tag":501,"props":7070,"children":7071},{"style":557},[7072],{"type":418,"value":7045},{"type":413,"tag":501,"props":7074,"children":7075},{"style":519},[7076],{"type":418,"value":794},{"type":413,"tag":414,"props":7078,"children":7079},{},[7080],{"type":418,"value":7081},"This script should be self-explanatory if you have already played a little with Azure CLI. Basically, what it does is:",{"type":413,"tag":1523,"props":7083,"children":7084},{},[7085,7090,7102,7107,7112],{"type":413,"tag":1527,"props":7086,"children":7087},{},[7088],{"type":418,"value":7089},"create an azure SQL server",{"type":413,"tag":1527,"props":7091,"children":7092},{},[7093,7095,7100],{"type":418,"value":7094},"configure the server firewall to allow you to query it from your local IP address (if you are executing the script from cloud shell, replace ",{"type":413,"tag":443,"props":7096,"children":7098},{"className":7097},[],[7099],{"type":418,"value":6375},{"type":418,"value":7101}," variable with your local machine IP)",{"type":413,"tag":1527,"props":7103,"children":7104},{},[7105],{"type":418,"value":7106},"create an azure SQL database with already tables and data in it from the sample AdventureWorksLT",{"type":413,"tag":1527,"props":7108,"children":7109},{},[7110],{"type":418,"value":7111},"set you logged in azure ad user as the AD administrator of the database",{"type":413,"tag":1527,"props":7113,"children":7114},{},[7115],{"type":418,"value":7116},"write in the console the connection string to use in your C# code to access the database",{"type":413,"tag":414,"props":7118,"children":7119},{},[7120],{"type":418,"value":7121},"If you want to customize something do not hesitate to modify the scripts and especially variables like the resources location, the SQL server user/password, or the name of the resources. This is a bash script but if you want to execute it in PowerShell, all the Azure CLI commands should work fine, you just have to change the variables declarations as the syntax is different in PowerShell. If you don't have Azure CLI installed on your laptop you can use Azure Cloud Shell to execute this script.",{"type":413,"tag":466,"props":7123,"children":7124},{"icon":468},[7125],{"type":413,"tag":414,"props":7126,"children":7127},{},[7128,7130,7135],{"type":418,"value":7129},"If you are new to Azure CLI, you can read my article ",{"type":413,"tag":432,"props":7131,"children":7133},{"href":458,"rel":7132},[436],[7134],{"type":418,"value":15},{"type":418,"value":564},{"type":413,"tag":1556,"props":7137,"children":7139},{"id":7138},"querying-the-database-from-a-minima-api-in-c",[7140],{"type":418,"value":7141},"Querying the database from a minima API in C#",{"type":413,"tag":414,"props":7143,"children":7144},{},[7145,7147,7154],{"type":418,"value":7146},"Usually, I like to create a console application (with the ",{"type":413,"tag":432,"props":7148,"children":7151},{"href":7149,"rel":7150},"https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0&tabs=visual-studio#worker-service-template",[436],[7152],{"type":418,"value":7153},"worker service template",{"type":418,"value":7155}," for instance) for my samples, yet this time I decided to try the new minimal APIs from .NET 6 (currently in preview).",{"type":413,"tag":414,"props":7157,"children":7158},{},[7159,7161,7167],{"type":418,"value":7160},"Minimal APIs would probably deserve an entire blog post, but let's just say a minimal API in .NET 6 allow you to build a small HTTP API with less ceremony than a classic controller-based API. As all the code can be written in a ",{"type":413,"tag":443,"props":7162,"children":7164},{"className":7163},[],[7165],{"type":418,"value":7166},"Program.cs",{"type":418,"value":7168}," file, so it's very convenient when you want to quickly build a web application without too much complexity (especially if you are new to ASP.NET Core) or if you are developing a small microservice.",{"type":413,"tag":492,"props":7170,"children":7172},{"className":494,"code":7171,"language":326,"meta":401,"style":401},"using Dapper;\nusing Microsoft.Data.SqlClient;\n\nvar builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n\nif (app.Environment.IsDevelopment())\n{\n    app.UseDeveloperExceptionPage();\n}\n\napp.MapGet(\"/\", async () =>\n{\n    using var connection = new SqlConnection(\"Server=server-testingmsi28497.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi28497;\");\n    var products = await connection.QueryAsync\u003CProduct>(\"SELECT TOP 10 ProductID, Name from [SalesLT].[Product]\");\n    return products;\n});\n\napp.Run();\n\npublic record Product(int ProductID, string Name);\n",[7173],{"type":413,"tag":443,"props":7174,"children":7175},{"__ignoreMap":401},[7176,7192,7225,7232,7275,7308,7315,7355,7362,7383,7390,7397,7449,7456,7505,7570,7585,7592,7599,7619,7626],{"type":413,"tag":501,"props":7177,"children":7178},{"class":503,"line":504},[7179,7183,7188],{"type":413,"tag":501,"props":7180,"children":7181},{"style":1402},[7182],{"type":418,"value":5522},{"type":413,"tag":501,"props":7184,"children":7185},{"style":557},[7186],{"type":418,"value":7187}," Dapper",{"type":413,"tag":501,"props":7189,"children":7190},{"style":519},[7191],{"type":418,"value":1430},{"type":413,"tag":501,"props":7193,"children":7194},{"class":503,"line":540},[7195,7199,7204,7208,7213,7217,7221],{"type":413,"tag":501,"props":7196,"children":7197},{"style":1402},[7198],{"type":418,"value":5522},{"type":413,"tag":501,"props":7200,"children":7201},{"style":557},[7202],{"type":418,"value":7203}," Microsoft",{"type":413,"tag":501,"props":7205,"children":7206},{"style":519},[7207],{"type":418,"value":564},{"type":413,"tag":501,"props":7209,"children":7210},{"style":557},[7211],{"type":418,"value":7212},"Data",{"type":413,"tag":501,"props":7214,"children":7215},{"style":519},[7216],{"type":418,"value":564},{"type":413,"tag":501,"props":7218,"children":7219},{"style":557},[7220],{"type":418,"value":5959},{"type":413,"tag":501,"props":7222,"children":7223},{"style":519},[7224],{"type":418,"value":1430},{"type":413,"tag":501,"props":7226,"children":7227},{"class":503,"line":598},[7228],{"type":413,"tag":501,"props":7229,"children":7230},{"emptyLinePlaceholder":653},[7231],{"type":418,"value":656},{"type":413,"tag":501,"props":7233,"children":7234},{"class":503,"line":649},[7235,7239,7244,7248,7253,7257,7262,7266,7271],{"type":413,"tag":501,"props":7236,"children":7237},{"style":508},[7238],{"type":418,"value":511},{"type":413,"tag":501,"props":7240,"children":7241},{"style":508},[7242],{"type":418,"value":7243}," builder",{"type":413,"tag":501,"props":7245,"children":7246},{"style":519},[7247],{"type":418,"value":522},{"type":413,"tag":501,"props":7249,"children":7250},{"style":557},[7251],{"type":418,"value":7252}," WebApplication",{"type":413,"tag":501,"props":7254,"children":7255},{"style":519},[7256],{"type":418,"value":564},{"type":413,"tag":501,"props":7258,"children":7259},{"style":567},[7260],{"type":418,"value":7261},"CreateBuilder",{"type":413,"tag":501,"props":7263,"children":7264},{"style":519},[7265],{"type":418,"value":575},{"type":413,"tag":501,"props":7267,"children":7268},{"style":557},[7269],{"type":418,"value":7270},"args",{"type":413,"tag":501,"props":7272,"children":7273},{"style":519},[7274],{"type":418,"value":595},{"type":413,"tag":501,"props":7276,"children":7277},{"class":503,"line":659},[7278,7282,7287,7291,7295,7299,7304],{"type":413,"tag":501,"props":7279,"children":7280},{"style":508},[7281],{"type":418,"value":511},{"type":413,"tag":501,"props":7283,"children":7284},{"style":508},[7285],{"type":418,"value":7286}," app",{"type":413,"tag":501,"props":7288,"children":7289},{"style":519},[7290],{"type":418,"value":522},{"type":413,"tag":501,"props":7292,"children":7293},{"style":557},[7294],{"type":418,"value":7243},{"type":413,"tag":501,"props":7296,"children":7297},{"style":519},[7298],{"type":418,"value":564},{"type":413,"tag":501,"props":7300,"children":7301},{"style":567},[7302],{"type":418,"value":7303},"Build",{"type":413,"tag":501,"props":7305,"children":7306},{"style":519},[7307],{"type":418,"value":537},{"type":413,"tag":501,"props":7309,"children":7310},{"class":503,"line":716},[7311],{"type":413,"tag":501,"props":7312,"children":7313},{"emptyLinePlaceholder":653},[7314],{"type":418,"value":656},{"type":413,"tag":501,"props":7316,"children":7317},{"class":503,"line":725},[7318,7323,7327,7332,7336,7341,7345,7350],{"type":413,"tag":501,"props":7319,"children":7320},{"style":1812},[7321],{"type":418,"value":7322},"if",{"type":413,"tag":501,"props":7324,"children":7325},{"style":519},[7326],{"type":418,"value":5527},{"type":413,"tag":501,"props":7328,"children":7329},{"style":557},[7330],{"type":418,"value":7331},"app",{"type":413,"tag":501,"props":7333,"children":7334},{"style":519},[7335],{"type":418,"value":564},{"type":413,"tag":501,"props":7337,"children":7338},{"style":557},[7339],{"type":418,"value":7340},"Environment",{"type":413,"tag":501,"props":7342,"children":7343},{"style":519},[7344],{"type":418,"value":564},{"type":413,"tag":501,"props":7346,"children":7347},{"style":567},[7348],{"type":418,"value":7349},"IsDevelopment",{"type":413,"tag":501,"props":7351,"children":7352},{"style":519},[7353],{"type":418,"value":7354},"())\n",{"type":413,"tag":501,"props":7356,"children":7357},{"class":503,"line":748},[7358],{"type":413,"tag":501,"props":7359,"children":7360},{"style":519},[7361],{"type":418,"value":722},{"type":413,"tag":501,"props":7363,"children":7364},{"class":503,"line":769},[7365,7370,7374,7379],{"type":413,"tag":501,"props":7366,"children":7367},{"style":557},[7368],{"type":418,"value":7369},"    app",{"type":413,"tag":501,"props":7371,"children":7372},{"style":519},[7373],{"type":418,"value":564},{"type":413,"tag":501,"props":7375,"children":7376},{"style":567},[7377],{"type":418,"value":7378},"UseDeveloperExceptionPage",{"type":413,"tag":501,"props":7380,"children":7381},{"style":519},[7382],{"type":418,"value":537},{"type":413,"tag":501,"props":7384,"children":7385},{"class":503,"line":797},[7386],{"type":413,"tag":501,"props":7387,"children":7388},{"style":519},[7389],{"type":418,"value":2530},{"type":413,"tag":501,"props":7391,"children":7392},{"class":503,"line":1145},[7393],{"type":413,"tag":501,"props":7394,"children":7395},{"emptyLinePlaceholder":653},[7396],{"type":418,"value":656},{"type":413,"tag":501,"props":7398,"children":7399},{"class":503,"line":1154},[7400,7404,7408,7413,7417,7421,7426,7430,7434,7440,7445],{"type":413,"tag":501,"props":7401,"children":7402},{"style":557},[7403],{"type":418,"value":7331},{"type":413,"tag":501,"props":7405,"children":7406},{"style":519},[7407],{"type":418,"value":564},{"type":413,"tag":501,"props":7409,"children":7410},{"style":567},[7411],{"type":418,"value":7412},"MapGet",{"type":413,"tag":501,"props":7414,"children":7415},{"style":519},[7416],{"type":418,"value":575},{"type":413,"tag":501,"props":7418,"children":7419},{"style":519},[7420],{"type":418,"value":580},{"type":413,"tag":501,"props":7422,"children":7423},{"style":583},[7424],{"type":418,"value":7425},"/",{"type":413,"tag":501,"props":7427,"children":7428},{"style":519},[7429],{"type":418,"value":580},{"type":413,"tag":501,"props":7431,"children":7432},{"style":519},[7433],{"type":418,"value":704},{"type":413,"tag":501,"props":7435,"children":7437},{"style":7436},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[7438],{"type":418,"value":7439}," async",{"type":413,"tag":501,"props":7441,"children":7442},{"style":519},[7443],{"type":418,"value":7444}," ()",{"type":413,"tag":501,"props":7446,"children":7447},{"style":519},[7448],{"type":418,"value":1753},{"type":413,"tag":501,"props":7450,"children":7451},{"class":503,"line":4568},[7452],{"type":413,"tag":501,"props":7453,"children":7454},{"style":519},[7455],{"type":418,"value":722},{"type":413,"tag":501,"props":7457,"children":7458},{"class":503,"line":4577},[7459,7464,7468,7472,7476,7480,7484,7488,7492,7497,7501],{"type":413,"tag":501,"props":7460,"children":7461},{"style":1812},[7462],{"type":418,"value":7463},"    using",{"type":413,"tag":501,"props":7465,"children":7466},{"style":508},[7467],{"type":418,"value":5776},{"type":413,"tag":501,"props":7469,"children":7470},{"style":508},[7471],{"type":418,"value":5575},{"type":413,"tag":501,"props":7473,"children":7474},{"style":519},[7475],{"type":418,"value":522},{"type":413,"tag":501,"props":7477,"children":7478},{"style":519},[7479],{"type":418,"value":527},{"type":413,"tag":501,"props":7481,"children":7482},{"style":508},[7483],{"type":418,"value":5549},{"type":413,"tag":501,"props":7485,"children":7486},{"style":519},[7487],{"type":418,"value":575},{"type":413,"tag":501,"props":7489,"children":7490},{"style":519},[7491],{"type":418,"value":580},{"type":413,"tag":501,"props":7493,"children":7494},{"style":583},[7495],{"type":418,"value":7496},"Server=server-testingmsi28497.database.windows.net; Authentication=Active Directory Default; Database=database-testingmsi28497;",{"type":413,"tag":501,"props":7498,"children":7499},{"style":519},[7500],{"type":418,"value":580},{"type":413,"tag":501,"props":7502,"children":7503},{"style":519},[7504],{"type":418,"value":595},{"type":413,"tag":501,"props":7506,"children":7507},{"class":503,"line":4591},[7508,7513,7518,7522,7526,7530,7534,7539,7543,7548,7553,7557,7562,7566],{"type":413,"tag":501,"props":7509,"children":7510},{"style":508},[7511],{"type":418,"value":7512},"    var",{"type":413,"tag":501,"props":7514,"children":7515},{"style":508},[7516],{"type":418,"value":7517}," products",{"type":413,"tag":501,"props":7519,"children":7520},{"style":519},[7521],{"type":418,"value":522},{"type":413,"tag":501,"props":7523,"children":7524},{"style":519},[7525],{"type":418,"value":5701},{"type":413,"tag":501,"props":7527,"children":7528},{"style":557},[7529],{"type":418,"value":5575},{"type":413,"tag":501,"props":7531,"children":7532},{"style":519},[7533],{"type":418,"value":564},{"type":413,"tag":501,"props":7535,"children":7536},{"style":567},[7537],{"type":418,"value":7538},"QueryAsync",{"type":413,"tag":501,"props":7540,"children":7541},{"style":519},[7542],{"type":418,"value":2497},{"type":413,"tag":501,"props":7544,"children":7545},{"style":508},[7546],{"type":418,"value":7547},"Product",{"type":413,"tag":501,"props":7549,"children":7550},{"style":519},[7551],{"type":418,"value":7552},">(",{"type":413,"tag":501,"props":7554,"children":7555},{"style":519},[7556],{"type":418,"value":580},{"type":413,"tag":501,"props":7558,"children":7559},{"style":583},[7560],{"type":418,"value":7561},"SELECT TOP 10 ProductID, Name from [SalesLT].[Product]",{"type":413,"tag":501,"props":7563,"children":7564},{"style":519},[7565],{"type":418,"value":580},{"type":413,"tag":501,"props":7567,"children":7568},{"style":519},[7569],{"type":418,"value":595},{"type":413,"tag":501,"props":7571,"children":7572},{"class":503,"line":4600},[7573,7577,7581],{"type":413,"tag":501,"props":7574,"children":7575},{"style":1812},[7576],{"type":418,"value":1815},{"type":413,"tag":501,"props":7578,"children":7579},{"style":557},[7580],{"type":418,"value":7517},{"type":413,"tag":501,"props":7582,"children":7583},{"style":519},[7584],{"type":418,"value":1430},{"type":413,"tag":501,"props":7586,"children":7587},{"class":503,"line":4630},[7588],{"type":413,"tag":501,"props":7589,"children":7590},{"style":519},[7591],{"type":418,"value":803},{"type":413,"tag":501,"props":7593,"children":7594},{"class":503,"line":4660},[7595],{"type":413,"tag":501,"props":7596,"children":7597},{"emptyLinePlaceholder":653},[7598],{"type":418,"value":656},{"type":413,"tag":501,"props":7600,"children":7601},{"class":503,"line":4669},[7602,7606,7610,7615],{"type":413,"tag":501,"props":7603,"children":7604},{"style":557},[7605],{"type":418,"value":7331},{"type":413,"tag":501,"props":7607,"children":7608},{"style":519},[7609],{"type":418,"value":564},{"type":413,"tag":501,"props":7611,"children":7612},{"style":567},[7613],{"type":418,"value":7614},"Run",{"type":413,"tag":501,"props":7616,"children":7617},{"style":519},[7618],{"type":418,"value":537},{"type":413,"tag":501,"props":7620,"children":7621},{"class":503,"line":4681},[7622],{"type":413,"tag":501,"props":7623,"children":7624},{"emptyLinePlaceholder":653},[7625],{"type":418,"value":656},{"type":413,"tag":501,"props":7627,"children":7628},{"class":503,"line":4689},[7629,7634,7639,7644,7649,7654,7658,7662,7667],{"type":413,"tag":501,"props":7630,"children":7631},{"style":7436},[7632],{"type":418,"value":7633},"public",{"type":413,"tag":501,"props":7635,"children":7636},{"style":508},[7637],{"type":418,"value":7638}," record",{"type":413,"tag":501,"props":7640,"children":7641},{"style":508},[7642],{"type":418,"value":7643}," Product",{"type":413,"tag":501,"props":7645,"children":7646},{"style":519},[7647],{"type":418,"value":7648},"(int",{"type":413,"tag":501,"props":7650,"children":7651},{"style":508},[7652],{"type":418,"value":7653}," ProductID",{"type":413,"tag":501,"props":7655,"children":7656},{"style":519},[7657],{"type":418,"value":704},{"type":413,"tag":501,"props":7659,"children":7660},{"style":519},[7661],{"type":418,"value":5737},{"type":413,"tag":501,"props":7663,"children":7664},{"style":508},[7665],{"type":418,"value":7666}," Name",{"type":413,"tag":501,"props":7668,"children":7669},{"style":519},[7670],{"type":418,"value":595},{"type":413,"tag":414,"props":7672,"children":7673},{},[7674],{"type":418,"value":7675},"As you can see this code is only 26 lines long:",{"type":413,"tag":1523,"props":7677,"children":7678},{},[7679,7692,7704,7716],{"type":413,"tag":1527,"props":7680,"children":7681},{},[7682,7684,7690],{"type":418,"value":7683},"there is only one route, that returns the Product identifiers and names from the table ",{"type":413,"tag":443,"props":7685,"children":7687},{"className":7686},[],[7688],{"type":418,"value":7689},"[SalesLT].[Product]",{"type":418,"value":7691}," of the database created with the previous Azure CLI script",{"type":413,"tag":1527,"props":7693,"children":7694},{},[7695,7697,7702],{"type":418,"value":7696},"the SQL query is done by using the micro ORM ",{"type":413,"tag":432,"props":7698,"children":7700},{"href":1684,"rel":7699},[436],[7701],{"type":418,"value":1688},{"type":418,"value":7703}," which simplifies the boilerplate code to query an SQL database while keeping performance",{"type":413,"tag":1527,"props":7705,"children":7706},{},[7707,7709,7714],{"type":418,"value":7708},"the result of the SQL query is mapped to a record class ",{"type":413,"tag":443,"props":7710,"children":7712},{"className":7711},[],[7713],{"type":418,"value":7547},{"type":418,"value":7715}," which is declared in one line",{"type":413,"tag":1527,"props":7717,"children":7718},{},[7719,7721,7726,7728,7733],{"type":418,"value":7720},"the code uses ",{"type":413,"tag":443,"props":7722,"children":7724},{"className":7723},[],[7725],{"type":418,"value":448},{"type":418,"value":7727}," v3.0.0 with the ",{"type":413,"tag":443,"props":7729,"children":7731},{"className":7730},[],[7732],{"type":418,"value":5406},{"type":418,"value":5934},{"type":413,"tag":414,"props":7735,"children":7736},{},[7737],{"type":413,"tag":1580,"props":7738,"children":7742},{"alt":7739,"className":7740,"src":7741},"C# code querying an SQL Database using Active Directory Default authentication mode.",[1584,1585],"/posts/images/sqlclient_minapi_1.png",[],{"type":413,"tag":466,"props":7744,"children":7745},{"icon":468},[7746],{"type":413,"tag":414,"props":7747,"children":7748},{},[7749,7751,7757],{"type":418,"value":7750},"To keep things simple, I am connecting to the database with the Azure AD account which is an admin of the SQL server. But I could also have assigned a role with lower permissions to my account, see ",{"type":413,"tag":432,"props":7752,"children":7755},{"href":7753,"rel":7754},"https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi#grant-permissions-to-managed-identity",[436],[7756],{"type":418,"value":3536},{"type":418,"value":7758}," for more information on how to do that.",{"type":413,"tag":420,"props":7760,"children":7762},{"id":7761},"to-conclude",[7763],{"type":418,"value":7764},"To conclude",{"type":413,"tag":414,"props":7766,"children":7767},{},[7768,7770,7776],{"type":418,"value":7769},"While building an application interacting with Azure we often neglect to use mechanisms like Azure AD authentication that remove the need for secrets. But as we have seen in this article some libraries like ",{"type":413,"tag":443,"props":7771,"children":7773},{"className":7772},[],[7774],{"type":418,"value":7775},"Microsoft.Data.Sql.Client",{"type":418,"value":7777}," or the Azure SDKs allow us to do that quite easily. I love how connecting to an Azure SQL Database in C# is becoming more simple and more secure at the same time.",{"type":413,"tag":3363,"props":7779,"children":7780},{},[7781],{"type":418,"value":3367},{"title":401,"searchDepth":540,"depth":540,"links":7783},[7784,7785,7786,7788,7792],{"id":5439,"depth":540,"text":5442},{"id":5635,"depth":540,"text":5638},{"id":5924,"depth":540,"text":7787},"Here comes Active Directory Default authentication mode",{"id":6064,"depth":540,"text":6067,"children":7789},[7790,7791],{"id":6075,"depth":598,"text":6078},{"id":7138,"depth":598,"text":7141},{"id":7761,"depth":540,"text":7764},"content:1.posts:20.sqlclient-active-directory-authent.md","1.posts/20.sqlclient-active-directory-authent.md",{"_path":28,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":27,"description":7796,"lead":7797,"date":7798,"image":7799,"badge":7801,"tags":7802,"body":7803,"_type":3386,"_id":11798,"_source":3388,"_file":11799,"_extension":3390},"If you have no interest in reading the blog post and just want the final script, you can find it on this GitHub repository.","Creating a PowerShell script to configure SSO for the tab of a Teams application.","2020-06-15T00:00:00.000Z",{"src":7800},"/images/shell_1.jpg",{"label":266},[246,249,252],{"type":410,"children":7804,"toc":11783},[7805,7817,7823,7835,7849,7855,7878,7883,7889,7903,8077,8082,8088,8093,8139,8152,8183,8189,8202,8257,8263,8276,8378,8384,8404,8763,8775,9230,9236,9241,9591,9596,9830,9836,9850,10051,10064,10709,10728,11154,11160,11173,11178,11379,11399,11761,11767,11779],{"type":413,"tag":414,"props":7806,"children":7807},{},[7808,7810,7816],{"type":418,"value":7809},"If you have no interest in reading the blog post and just want the final script, you can find it on this ",{"type":413,"tag":432,"props":7811,"children":7814},{"href":7812,"rel":7813},"https://github.com/TechWatching/TeamsDev/blob/master/infra/Scripts/ConfigureTeamsTabSSO.ps1",[436],[7815],{"type":418,"value":1617},{"type":418,"value":564},{"type":413,"tag":420,"props":7818,"children":7820},{"id":7819},"context",[7821],{"type":418,"value":7822},"Context",{"type":413,"tag":414,"props":7824,"children":7825},{},[7826,7828,7833],{"type":418,"value":7827},"Several months ago, I supervised a student project aiming at developing a Teams application for my company. The application is mainly composed of a tab where Human Resources people can see information about arrivals and departures in the company. Once the project was finished and the first version of the application was available, I provisioned the application infrastructure on my company Azure tenant using ",{"type":413,"tag":432,"props":7829,"children":7831},{"href":3568,"rel":7830},[436],[7832],{"type":418,"value":312},{"type":418,"value":7834}," which is a nice infrastructure as code platform.",{"type":413,"tag":414,"props":7836,"children":7837},{},[7838,7840,7847],{"type":418,"value":7839},"However, configuring Single Sign-On for the tab of the application did not seem possible with Pulumi as it internally uses Terraform Provider for AzureAD which at the time of writing doesn't have all functionalities necessary to configure this. The ",{"type":413,"tag":432,"props":7841,"children":7844},{"href":7842,"rel":7843},"http://aka.ms/teams-sso",[436],[7845],{"type":418,"value":7846},"documentation about SSO for Teams tab",{"type":418,"value":7848}," currently lists all the steps necessary to configure it from the Azure Portal, however, it mentions nothing about automating it, hence this blog post.",{"type":413,"tag":420,"props":7850,"children":7852},{"id":7851},"steps-to-create-the-powershell-script",[7853],{"type":418,"value":7854},"Steps to create the PowerShell script",{"type":413,"tag":414,"props":7856,"children":7857},{},[7858,7860,7867,7869,7876],{"type":418,"value":7859},"Usually, I prefer Azure CLI to PowerShell as I find it easier to find commands I need, but Azure CLI doesn't have yet the necessary commands. Most of the code comes from ",{"type":413,"tag":432,"props":7861,"children":7864},{"href":7862,"rel":7863},"https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/blob/master/3.-Web-api-call-Microsoft-graph-for-personal-accounts/AppCreationScripts/Configure.ps1",[436],[7865],{"type":418,"value":7866},"this script",{"type":418,"value":7868}," located in a repository of the ",{"type":413,"tag":432,"props":7870,"children":7873},{"href":7871,"rel":7872},"https://github.com/Azure-Samples",[436],[7874],{"type":418,"value":7875},"Azure Samples GitHub organization",{"type":418,"value":7877},". I took only what was necessary for Teams Tab SSO, adapted it to use Microsoft Graph objects/commands, and added missing commands.",{"type":413,"tag":414,"props":7879,"children":7880},{},[7881],{"type":418,"value":7882},"I am not an expert in PowerShell so there might be things to improve in the final script, but I hope the following steps will help you to understand how to configure SSO for your Teams Tab.",{"type":413,"tag":1556,"props":7884,"children":7886},{"id":7885},"interacting-with-azure-active-directory",[7887],{"type":418,"value":7888},"Interacting with Azure Active Directory",{"type":413,"tag":414,"props":7890,"children":7891},{},[7892,7894,7901],{"type":418,"value":7893},"PowerShell has a module called ",{"type":413,"tag":432,"props":7895,"children":7898},{"href":7896,"rel":7897},"https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0",[436],[7899],{"type":418,"value":7900},"AzureAd",{"type":418,"value":7902}," that allow us to interact with Azure Active Directory.\nThe first step is to install this module if not already installed, import it and authenticate to Azure AD to be able to use Active Directory commands once authenticated.",{"type":413,"tag":492,"props":7904,"children":7906},{"className":2689,"code":7905,"language":248,"meta":401,"style":401},"if ($null -eq (Get-Module -ListAvailable -Name \"AzureAD\")) { \n    Install-Module -Name \"AzureAD\" -Force\n}\n\nImport-Module AzureAD\n\nConnect-AzureAD -TenantId $tenantId\n",[7907],{"type":413,"tag":443,"props":7908,"children":7909},{"__ignoreMap":401},[7910,7980,8017,8024,8031,8044,8051],{"type":413,"tag":501,"props":7911,"children":7912},{"class":503,"line":504},[7913,7917,7922,7927,7931,7936,7940,7945,7949,7954,7958,7963,7967,7972,7976],{"type":413,"tag":501,"props":7914,"children":7915},{"style":1812},[7916],{"type":418,"value":7322},{"type":413,"tag":501,"props":7918,"children":7919},{"style":519},[7920],{"type":418,"value":7921}," ($null",{"type":413,"tag":501,"props":7923,"children":7924},{"style":519},[7925],{"type":418,"value":7926}," -eq",{"type":413,"tag":501,"props":7928,"children":7929},{"style":519},[7930],{"type":418,"value":5527},{"type":413,"tag":501,"props":7932,"children":7933},{"style":567},[7934],{"type":418,"value":7935},"Get-Module",{"type":413,"tag":501,"props":7937,"children":7938},{"style":519},[7939],{"type":418,"value":2758},{"type":413,"tag":501,"props":7941,"children":7942},{"style":557},[7943],{"type":418,"value":7944},"ListAvailable ",{"type":413,"tag":501,"props":7946,"children":7947},{"style":519},[7948],{"type":418,"value":2707},{"type":413,"tag":501,"props":7950,"children":7951},{"style":557},[7952],{"type":418,"value":7953},"Name ",{"type":413,"tag":501,"props":7955,"children":7956},{"style":519},[7957],{"type":418,"value":580},{"type":413,"tag":501,"props":7959,"children":7960},{"style":583},[7961],{"type":418,"value":7962},"AzureAD",{"type":413,"tag":501,"props":7964,"children":7965},{"style":519},[7966],{"type":418,"value":580},{"type":413,"tag":501,"props":7968,"children":7969},{"style":519},[7970],{"type":418,"value":7971},"))",{"type":413,"tag":501,"props":7973,"children":7974},{"style":519},[7975],{"type":418,"value":2512},{"type":413,"tag":501,"props":7977,"children":7978},{"style":557},[7979],{"type":418,"value":1806},{"type":413,"tag":501,"props":7981,"children":7982},{"class":503,"line":540},[7983,7988,7992,7996,8000,8004,8008,8012],{"type":413,"tag":501,"props":7984,"children":7985},{"style":567},[7986],{"type":418,"value":7987},"    Install-Module",{"type":413,"tag":501,"props":7989,"children":7990},{"style":519},[7991],{"type":418,"value":2758},{"type":413,"tag":501,"props":7993,"children":7994},{"style":557},[7995],{"type":418,"value":7953},{"type":413,"tag":501,"props":7997,"children":7998},{"style":519},[7999],{"type":418,"value":580},{"type":413,"tag":501,"props":8001,"children":8002},{"style":583},[8003],{"type":418,"value":7962},{"type":413,"tag":501,"props":8005,"children":8006},{"style":519},[8007],{"type":418,"value":580},{"type":413,"tag":501,"props":8009,"children":8010},{"style":519},[8011],{"type":418,"value":2758},{"type":413,"tag":501,"props":8013,"children":8014},{"style":557},[8015],{"type":418,"value":8016},"Force\n",{"type":413,"tag":501,"props":8018,"children":8019},{"class":503,"line":598},[8020],{"type":413,"tag":501,"props":8021,"children":8022},{"style":519},[8023],{"type":418,"value":2530},{"type":413,"tag":501,"props":8025,"children":8026},{"class":503,"line":649},[8027],{"type":413,"tag":501,"props":8028,"children":8029},{"emptyLinePlaceholder":653},[8030],{"type":418,"value":656},{"type":413,"tag":501,"props":8032,"children":8033},{"class":503,"line":659},[8034,8039],{"type":413,"tag":501,"props":8035,"children":8036},{"style":567},[8037],{"type":418,"value":8038},"Import-Module",{"type":413,"tag":501,"props":8040,"children":8041},{"style":557},[8042],{"type":418,"value":8043}," AzureAD\n",{"type":413,"tag":501,"props":8045,"children":8046},{"class":503,"line":716},[8047],{"type":413,"tag":501,"props":8048,"children":8049},{"emptyLinePlaceholder":653},[8050],{"type":418,"value":656},{"type":413,"tag":501,"props":8052,"children":8053},{"class":503,"line":725},[8054,8059,8063,8068,8072],{"type":413,"tag":501,"props":8055,"children":8056},{"style":567},[8057],{"type":418,"value":8058},"Connect-AzureAD",{"type":413,"tag":501,"props":8060,"children":8061},{"style":519},[8062],{"type":418,"value":2758},{"type":413,"tag":501,"props":8064,"children":8065},{"style":557},[8066],{"type":418,"value":8067},"TenantId ",{"type":413,"tag":501,"props":8069,"children":8070},{"style":519},[8071],{"type":418,"value":3293},{"type":413,"tag":501,"props":8073,"children":8074},{"style":557},[8075],{"type":418,"value":8076},"tenantId\n",{"type":413,"tag":414,"props":8078,"children":8079},{},[8080],{"type":418,"value":8081},"This will prompt us to log in with our AD account. We will see later in the article how we can avoid that if we are using this script in an Azure Pipeline.",{"type":413,"tag":1556,"props":8083,"children":8085},{"id":8084},"retrieving-the-application-registration",[8086],{"type":418,"value":8087},"Retrieving the application registration",{"type":413,"tag":414,"props":8089,"children":8090},{},[8091],{"type":418,"value":8092},"I already created my application registration in AD with Pulumi so I just have to retrieve it before configuring it.",{"type":413,"tag":492,"props":8094,"children":8096},{"className":2689,"code":8095,"language":248,"meta":401,"style":401},"$app = Get-AzureADMSApplication -ObjectId $applicationObjectId\n",[8097],{"type":413,"tag":443,"props":8098,"children":8099},{"__ignoreMap":401},[8100],{"type":413,"tag":501,"props":8101,"children":8102},{"class":503,"line":504},[8103,8107,8112,8116,8121,8125,8130,8134],{"type":413,"tag":501,"props":8104,"children":8105},{"style":519},[8106],{"type":418,"value":3293},{"type":413,"tag":501,"props":8108,"children":8109},{"style":557},[8110],{"type":418,"value":8111},"app ",{"type":413,"tag":501,"props":8113,"children":8114},{"style":519},[8115],{"type":418,"value":736},{"type":413,"tag":501,"props":8117,"children":8118},{"style":567},[8119],{"type":418,"value":8120}," Get-AzureADMSApplication",{"type":413,"tag":501,"props":8122,"children":8123},{"style":519},[8124],{"type":418,"value":2758},{"type":413,"tag":501,"props":8126,"children":8127},{"style":557},[8128],{"type":418,"value":8129},"ObjectId ",{"type":413,"tag":501,"props":8131,"children":8132},{"style":519},[8133],{"type":418,"value":3293},{"type":413,"tag":501,"props":8135,"children":8136},{"style":557},[8137],{"type":418,"value":8138},"applicationObjectId\n",{"type":413,"tag":414,"props":8140,"children":8141},{},[8142,8144,8150],{"type":418,"value":8143},"If you don't have an existing application registration you can create one with the ",{"type":413,"tag":443,"props":8145,"children":8147},{"className":8146},[],[8148],{"type":418,"value":8149},"New-AzureADMSApplication",{"type":418,"value":8151}," command.",{"type":413,"tag":466,"props":8153,"children":8155},{"icon":8154},"i-fluent-emoji-flat-gem-stone",[8156],{"type":413,"tag":414,"props":8157,"children":8158},{},[8159,8161,8167,8168,8174,8176,8181],{"type":418,"value":8160},"You may note that there are similar commands ",{"type":413,"tag":443,"props":8162,"children":8164},{"className":8163},[],[8165],{"type":418,"value":8166},"Get-AzureADApplication",{"type":418,"value":1503},{"type":413,"tag":443,"props":8169,"children":8171},{"className":8170},[],[8172],{"type":418,"value":8173},"New-AzureADApplication",{"type":418,"value":8175}," that exist. Both commands work fine but commands with ",{"type":413,"tag":5893,"props":8177,"children":8178},{},[8179],{"type":418,"value":8180},"MS",{"type":418,"value":8182}," in their name internally use Microsoft Graph which seems to be the modern way to interact with Azure AD.",{"type":413,"tag":1556,"props":8184,"children":8186},{"id":8185},"creating-the-service-principal",[8187],{"type":418,"value":8188},"Creating the service principal",{"type":413,"tag":414,"props":8190,"children":8191},{},[8192,8194,8201],{"type":418,"value":8193},"When you register an application in Azure Portal it creates an Application object and a Service Principal in your tenant. But if you create the Application outside the Azure Portal (Azure CLI, PowerShell, Pulumi, ...), you will have to create the Service Principal as well. Just as a reminder the ",{"type":413,"tag":432,"props":8195,"children":8198},{"href":8196,"rel":8197},"https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals#application-and-service-principal-relationship",[436],[8199],{"type":418,"value":8200},"application object should be considered as the global representation of your application for use across all tenants, and the service principal as the local representation for use in a specific tenant",{"type":418,"value":564},{"type":413,"tag":492,"props":8203,"children":8205},{"className":2689,"code":8204,"language":248,"meta":401,"style":401},"New-AzureADServicePrincipal -AppId $app.AppId -Tags {WindowsAzureActiveDirectoryIntegratedApp}\n",[8206],{"type":413,"tag":443,"props":8207,"children":8208},{"__ignoreMap":401},[8209],{"type":413,"tag":501,"props":8210,"children":8211},{"class":503,"line":504},[8212,8217,8221,8226,8230,8235,8239,8244,8248,8253],{"type":413,"tag":501,"props":8213,"children":8214},{"style":567},[8215],{"type":418,"value":8216},"New-AzureADServicePrincipal",{"type":413,"tag":501,"props":8218,"children":8219},{"style":519},[8220],{"type":418,"value":2758},{"type":413,"tag":501,"props":8222,"children":8223},{"style":557},[8224],{"type":418,"value":8225},"AppId ",{"type":413,"tag":501,"props":8227,"children":8228},{"style":519},[8229],{"type":418,"value":3293},{"type":413,"tag":501,"props":8231,"children":8232},{"style":557},[8233],{"type":418,"value":8234},"app.AppId ",{"type":413,"tag":501,"props":8236,"children":8237},{"style":519},[8238],{"type":418,"value":2707},{"type":413,"tag":501,"props":8240,"children":8241},{"style":557},[8242],{"type":418,"value":8243},"Tags ",{"type":413,"tag":501,"props":8245,"children":8246},{"style":519},[8247],{"type":418,"value":895},{"type":413,"tag":501,"props":8249,"children":8250},{"style":557},[8251],{"type":418,"value":8252},"WindowsAzureActiveDirectoryIntegratedApp",{"type":413,"tag":501,"props":8254,"children":8255},{"style":519},[8256],{"type":418,"value":2530},{"type":413,"tag":1556,"props":8258,"children":8260},{"id":8259},"exposing-an-application-as-an-api",[8261],{"type":418,"value":8262},"Exposing an application as an API",{"type":413,"tag":414,"props":8264,"children":8265},{},[8266,8268,8274],{"type":418,"value":8267},"To expose an application as an API, it is necessary to set the identifier URI of the application. We will use a variable ",{"type":413,"tag":443,"props":8269,"children":8271},{"className":8270},[],[8272],{"type":418,"value":8273},"$customDomainName",{"type":418,"value":8275}," to specify the custom domain of the application. Indeed as stated by the documentation, for the moment Teams Tab SSO does not support applications that use the azurewebsites.net domain.",{"type":413,"tag":492,"props":8277,"children":8279},{"className":2689,"code":8278,"language":248,"meta":401,"style":401},"$appId = $app.AppId\nSet-AzureADMSApplication -ObjectId $app.Id -IdentifierUris \"api://$customDomainName/$appId\"\n",[8280],{"type":413,"tag":443,"props":8281,"children":8282},{"__ignoreMap":401},[8283,8309],{"type":413,"tag":501,"props":8284,"children":8285},{"class":503,"line":504},[8286,8290,8295,8299,8304],{"type":413,"tag":501,"props":8287,"children":8288},{"style":519},[8289],{"type":418,"value":3293},{"type":413,"tag":501,"props":8291,"children":8292},{"style":557},[8293],{"type":418,"value":8294},"appId ",{"type":413,"tag":501,"props":8296,"children":8297},{"style":519},[8298],{"type":418,"value":736},{"type":413,"tag":501,"props":8300,"children":8301},{"style":519},[8302],{"type":418,"value":8303}," $",{"type":413,"tag":501,"props":8305,"children":8306},{"style":557},[8307],{"type":418,"value":8308},"app.AppId\n",{"type":413,"tag":501,"props":8310,"children":8311},{"class":503,"line":540},[8312,8317,8321,8325,8329,8334,8338,8343,8347,8352,8356,8361,8365,8369,8374],{"type":413,"tag":501,"props":8313,"children":8314},{"style":567},[8315],{"type":418,"value":8316},"Set-AzureADMSApplication",{"type":413,"tag":501,"props":8318,"children":8319},{"style":519},[8320],{"type":418,"value":2758},{"type":413,"tag":501,"props":8322,"children":8323},{"style":557},[8324],{"type":418,"value":8129},{"type":413,"tag":501,"props":8326,"children":8327},{"style":519},[8328],{"type":418,"value":3293},{"type":413,"tag":501,"props":8330,"children":8331},{"style":557},[8332],{"type":418,"value":8333},"app.Id ",{"type":413,"tag":501,"props":8335,"children":8336},{"style":519},[8337],{"type":418,"value":2707},{"type":413,"tag":501,"props":8339,"children":8340},{"style":557},[8341],{"type":418,"value":8342},"IdentifierUris ",{"type":413,"tag":501,"props":8344,"children":8345},{"style":519},[8346],{"type":418,"value":580},{"type":413,"tag":501,"props":8348,"children":8349},{"style":583},[8350],{"type":418,"value":8351},"api://",{"type":413,"tag":501,"props":8353,"children":8354},{"style":519},[8355],{"type":418,"value":3293},{"type":413,"tag":501,"props":8357,"children":8358},{"style":557},[8359],{"type":418,"value":8360},"customDomainName",{"type":413,"tag":501,"props":8362,"children":8363},{"style":583},[8364],{"type":418,"value":7425},{"type":413,"tag":501,"props":8366,"children":8367},{"style":519},[8368],{"type":418,"value":3293},{"type":413,"tag":501,"props":8370,"children":8371},{"style":557},[8372],{"type":418,"value":8373},"appId",{"type":413,"tag":501,"props":8375,"children":8376},{"style":519},[8377],{"type":418,"value":794},{"type":413,"tag":1556,"props":8379,"children":8381},{"id":8380},"creating-the-access_as_user-scope",[8382],{"type":418,"value":8383},"Creating the access_as_user scope",{"type":413,"tag":414,"props":8385,"children":8386},{},[8387,8389,8395,8397,8402],{"type":418,"value":8388},"Teams Tab SSO works by making the Teams client (whether it be Teams mobile app, desktop app, or web app) ask for an Azure AD token with the scope ",{"type":413,"tag":443,"props":8390,"children":8392},{"className":8391},[],[8393],{"type":418,"value":8394},"access_as_user",{"type":418,"value":8396}," of the Tab application you developed. So we need to create a scope ",{"type":413,"tag":443,"props":8398,"children":8400},{"className":8399},[],[8401],{"type":418,"value":8394},{"type":418,"value":8403}," in the application.",{"type":413,"tag":492,"props":8405,"children":8407},{"className":2689,"code":8406,"language":248,"meta":401,"style":401},"# Add all existing scopes first\n$scopes = New-Object System.Collections.Generic.List[Microsoft.Open.MsGraph.Model.PermissionScope]\n$app.Api.Oauth2PermissionScopes | foreach-object { $scopes.Add($_) }\n$scope = CreateScope -value \"access_as_user\"  `\n    -userConsentDisplayName \"Teams can access the user’s profile\"  `\n    -userConsentDescription \"Allows Teams to call the app’s web APIs as the current user.\"  `\n    -adminConsentDisplayName \"Teams can access your user profile and make requests on your behalf\"  `\n    -adminConsentDescription \"Enable Teams to call this app’s APIs with the same rights that you have\"\n$scopes.Add($scope)\n$app.Api.Oauth2PermissionScopes = $scopes\nSet-AzureADMSApplication -ObjectId $app.Id -Api $app.Api\n",[8408],{"type":413,"tag":443,"props":8409,"children":8410},{"__ignoreMap":401},[8411,8419,8460,8514,8561,8591,8620,8649,8674,8698,8722],{"type":413,"tag":501,"props":8412,"children":8413},{"class":503,"line":504},[8414],{"type":413,"tag":501,"props":8415,"children":8416},{"style":1766},[8417],{"type":418,"value":8418},"# Add all existing scopes first\n",{"type":413,"tag":501,"props":8420,"children":8421},{"class":503,"line":540},[8422,8426,8431,8435,8440,8445,8450,8455],{"type":413,"tag":501,"props":8423,"children":8424},{"style":519},[8425],{"type":418,"value":3293},{"type":413,"tag":501,"props":8427,"children":8428},{"style":557},[8429],{"type":418,"value":8430},"scopes ",{"type":413,"tag":501,"props":8432,"children":8433},{"style":519},[8434],{"type":418,"value":736},{"type":413,"tag":501,"props":8436,"children":8437},{"style":567},[8438],{"type":418,"value":8439}," New-Object",{"type":413,"tag":501,"props":8441,"children":8442},{"style":557},[8443],{"type":418,"value":8444}," System.Collections.Generic.List",{"type":413,"tag":501,"props":8446,"children":8447},{"style":519},[8448],{"type":418,"value":8449},"[",{"type":413,"tag":501,"props":8451,"children":8452},{"style":7436},[8453],{"type":418,"value":8454},"Microsoft.Open.MsGraph.Model.PermissionScope",{"type":413,"tag":501,"props":8456,"children":8457},{"style":519},[8458],{"type":418,"value":8459},"]\n",{"type":413,"tag":501,"props":8461,"children":8462},{"class":503,"line":598},[8463,8467,8472,8477,8482,8486,8490,8495,8500,8505,8509],{"type":413,"tag":501,"props":8464,"children":8465},{"style":519},[8466],{"type":418,"value":3293},{"type":413,"tag":501,"props":8468,"children":8469},{"style":557},[8470],{"type":418,"value":8471},"app.Api.Oauth2PermissionScopes ",{"type":413,"tag":501,"props":8473,"children":8474},{"style":519},[8475],{"type":418,"value":8476},"|",{"type":413,"tag":501,"props":8478,"children":8479},{"style":567},[8480],{"type":418,"value":8481}," foreach-object",{"type":413,"tag":501,"props":8483,"children":8484},{"style":519},[8485],{"type":418,"value":2512},{"type":413,"tag":501,"props":8487,"children":8488},{"style":519},[8489],{"type":418,"value":8303},{"type":413,"tag":501,"props":8491,"children":8492},{"style":557},[8493],{"type":418,"value":8494},"scopes.Add",{"type":413,"tag":501,"props":8496,"children":8497},{"style":519},[8498],{"type":418,"value":8499},"($",{"type":413,"tag":501,"props":8501,"children":8502},{"style":557},[8503],{"type":418,"value":8504},"_",{"type":413,"tag":501,"props":8506,"children":8507},{"style":519},[8508],{"type":418,"value":5503},{"type":413,"tag":501,"props":8510,"children":8511},{"style":519},[8512],{"type":418,"value":8513}," }\n",{"type":413,"tag":501,"props":8515,"children":8516},{"class":503,"line":649},[8517,8521,8526,8530,8535,8539,8544,8548,8552,8556],{"type":413,"tag":501,"props":8518,"children":8519},{"style":519},[8520],{"type":418,"value":3293},{"type":413,"tag":501,"props":8522,"children":8523},{"style":557},[8524],{"type":418,"value":8525},"scope ",{"type":413,"tag":501,"props":8527,"children":8528},{"style":519},[8529],{"type":418,"value":736},{"type":413,"tag":501,"props":8531,"children":8532},{"style":557},[8533],{"type":418,"value":8534}," CreateScope ",{"type":413,"tag":501,"props":8536,"children":8537},{"style":519},[8538],{"type":418,"value":2707},{"type":413,"tag":501,"props":8540,"children":8541},{"style":557},[8542],{"type":418,"value":8543},"value ",{"type":413,"tag":501,"props":8545,"children":8546},{"style":519},[8547],{"type":418,"value":580},{"type":413,"tag":501,"props":8549,"children":8550},{"style":583},[8551],{"type":418,"value":8394},{"type":413,"tag":501,"props":8553,"children":8554},{"style":519},[8555],{"type":418,"value":580},{"type":413,"tag":501,"props":8557,"children":8558},{"style":519},[8559],{"type":418,"value":8560},"  `\n",{"type":413,"tag":501,"props":8562,"children":8563},{"class":503,"line":659},[8564,8569,8574,8578,8583,8587],{"type":413,"tag":501,"props":8565,"children":8566},{"style":519},[8567],{"type":418,"value":8568},"    -",{"type":413,"tag":501,"props":8570,"children":8571},{"style":557},[8572],{"type":418,"value":8573},"userConsentDisplayName ",{"type":413,"tag":501,"props":8575,"children":8576},{"style":519},[8577],{"type":418,"value":580},{"type":413,"tag":501,"props":8579,"children":8580},{"style":583},[8581],{"type":418,"value":8582},"Teams can access the user’s profile",{"type":413,"tag":501,"props":8584,"children":8585},{"style":519},[8586],{"type":418,"value":580},{"type":413,"tag":501,"props":8588,"children":8589},{"style":519},[8590],{"type":418,"value":8560},{"type":413,"tag":501,"props":8592,"children":8593},{"class":503,"line":716},[8594,8598,8603,8607,8612,8616],{"type":413,"tag":501,"props":8595,"children":8596},{"style":519},[8597],{"type":418,"value":8568},{"type":413,"tag":501,"props":8599,"children":8600},{"style":557},[8601],{"type":418,"value":8602},"userConsentDescription ",{"type":413,"tag":501,"props":8604,"children":8605},{"style":519},[8606],{"type":418,"value":580},{"type":413,"tag":501,"props":8608,"children":8609},{"style":583},[8610],{"type":418,"value":8611},"Allows Teams to call the app’s web APIs as the current user.",{"type":413,"tag":501,"props":8613,"children":8614},{"style":519},[8615],{"type":418,"value":580},{"type":413,"tag":501,"props":8617,"children":8618},{"style":519},[8619],{"type":418,"value":8560},{"type":413,"tag":501,"props":8621,"children":8622},{"class":503,"line":725},[8623,8627,8632,8636,8641,8645],{"type":413,"tag":501,"props":8624,"children":8625},{"style":519},[8626],{"type":418,"value":8568},{"type":413,"tag":501,"props":8628,"children":8629},{"style":557},[8630],{"type":418,"value":8631},"adminConsentDisplayName ",{"type":413,"tag":501,"props":8633,"children":8634},{"style":519},[8635],{"type":418,"value":580},{"type":413,"tag":501,"props":8637,"children":8638},{"style":583},[8639],{"type":418,"value":8640},"Teams can access your user profile and make requests on your behalf",{"type":413,"tag":501,"props":8642,"children":8643},{"style":519},[8644],{"type":418,"value":580},{"type":413,"tag":501,"props":8646,"children":8647},{"style":519},[8648],{"type":418,"value":8560},{"type":413,"tag":501,"props":8650,"children":8651},{"class":503,"line":748},[8652,8656,8661,8665,8670],{"type":413,"tag":501,"props":8653,"children":8654},{"style":519},[8655],{"type":418,"value":8568},{"type":413,"tag":501,"props":8657,"children":8658},{"style":557},[8659],{"type":418,"value":8660},"adminConsentDescription ",{"type":413,"tag":501,"props":8662,"children":8663},{"style":519},[8664],{"type":418,"value":580},{"type":413,"tag":501,"props":8666,"children":8667},{"style":583},[8668],{"type":418,"value":8669},"Enable Teams to call this app’s APIs with the same rights that you have",{"type":413,"tag":501,"props":8671,"children":8672},{"style":519},[8673],{"type":418,"value":794},{"type":413,"tag":501,"props":8675,"children":8676},{"class":503,"line":769},[8677,8681,8685,8689,8694],{"type":413,"tag":501,"props":8678,"children":8679},{"style":519},[8680],{"type":418,"value":3293},{"type":413,"tag":501,"props":8682,"children":8683},{"style":557},[8684],{"type":418,"value":8494},{"type":413,"tag":501,"props":8686,"children":8687},{"style":519},[8688],{"type":418,"value":8499},{"type":413,"tag":501,"props":8690,"children":8691},{"style":557},[8692],{"type":418,"value":8693},"scope",{"type":413,"tag":501,"props":8695,"children":8696},{"style":519},[8697],{"type":418,"value":5814},{"type":413,"tag":501,"props":8699,"children":8700},{"class":503,"line":797},[8701,8705,8709,8713,8717],{"type":413,"tag":501,"props":8702,"children":8703},{"style":519},[8704],{"type":418,"value":3293},{"type":413,"tag":501,"props":8706,"children":8707},{"style":557},[8708],{"type":418,"value":8471},{"type":413,"tag":501,"props":8710,"children":8711},{"style":519},[8712],{"type":418,"value":736},{"type":413,"tag":501,"props":8714,"children":8715},{"style":519},[8716],{"type":418,"value":8303},{"type":413,"tag":501,"props":8718,"children":8719},{"style":557},[8720],{"type":418,"value":8721},"scopes\n",{"type":413,"tag":501,"props":8723,"children":8724},{"class":503,"line":1145},[8725,8729,8733,8737,8741,8745,8749,8754,8758],{"type":413,"tag":501,"props":8726,"children":8727},{"style":567},[8728],{"type":418,"value":8316},{"type":413,"tag":501,"props":8730,"children":8731},{"style":519},[8732],{"type":418,"value":2758},{"type":413,"tag":501,"props":8734,"children":8735},{"style":557},[8736],{"type":418,"value":8129},{"type":413,"tag":501,"props":8738,"children":8739},{"style":519},[8740],{"type":418,"value":3293},{"type":413,"tag":501,"props":8742,"children":8743},{"style":557},[8744],{"type":418,"value":8333},{"type":413,"tag":501,"props":8746,"children":8747},{"style":519},[8748],{"type":418,"value":2707},{"type":413,"tag":501,"props":8750,"children":8751},{"style":557},[8752],{"type":418,"value":8753},"Api ",{"type":413,"tag":501,"props":8755,"children":8756},{"style":519},[8757],{"type":418,"value":3293},{"type":413,"tag":501,"props":8759,"children":8760},{"style":557},[8761],{"type":418,"value":8762},"app.Api\n",{"type":413,"tag":414,"props":8764,"children":8765},{},[8766,8768,8773],{"type":418,"value":8767},"This piece of PowerShell just ensures existing scopes won't be deleted when adding the scope ",{"type":413,"tag":443,"props":8769,"children":8771},{"className":8770},[],[8772],{"type":418,"value":8394},{"type":418,"value":8774},". Display names and descriptions of the new scope are the ones recommended in the documentation. This code calls a PowerShell function that simply creates the scope object.",{"type":413,"tag":492,"props":8776,"children":8778},{"className":2689,"code":8777,"language":248,"meta":401,"style":401},"\u003C#.Description\n   This function creates a new Azure AD scope (OAuth2Permission) with default and provided values\n#>  \nfunction CreateScope(\n    [string] $value,\n    [string] $userConsentDisplayName,\n    [string] $userConsentDescription,\n    [string] $adminConsentDisplayName,\n    [string] $adminConsentDescription)\n{\n    $scope = New-Object Microsoft.Open.MsGraph.Model.PermissionScope\n    $scope.Id = New-Guid\n    $scope.Value = $value\n    $scope.UserConsentDisplayName = $userConsentDisplayName\n    $scope.UserConsentDescription = $userConsentDescription\n    $scope.AdminConsentDisplayName = $adminConsentDisplayName\n    $scope.AdminConsentDescription = $adminConsentDescription\n    $scope.IsEnabled = $true\n    $scope.Type = \"User\"\n    return $scope\n}\n",[8779],{"type":413,"tag":443,"props":8780,"children":8781},{"__ignoreMap":401},[8782,8799,8807,8820,8838,8868,8896,8924,8952,8980,8987,9012,9033,9058,9083,9108,9133,9158,9179,9207,9223],{"type":413,"tag":501,"props":8783,"children":8784},{"class":503,"line":504},[8785,8790,8794],{"type":413,"tag":501,"props":8786,"children":8787},{"style":1766},[8788],{"type":418,"value":8789},"\u003C#",{"type":413,"tag":501,"props":8791,"children":8792},{"style":1766},[8793],{"type":418,"value":564},{"type":413,"tag":501,"props":8795,"children":8796},{"style":1812},[8797],{"type":418,"value":8798},"Description\n",{"type":413,"tag":501,"props":8800,"children":8801},{"class":503,"line":540},[8802],{"type":413,"tag":501,"props":8803,"children":8804},{"style":1766},[8805],{"type":418,"value":8806},"   This function creates a new Azure AD scope (OAuth2Permission) with default and provided values\n",{"type":413,"tag":501,"props":8808,"children":8809},{"class":503,"line":598},[8810,8815],{"type":413,"tag":501,"props":8811,"children":8812},{"style":1766},[8813],{"type":418,"value":8814},"#>",{"type":413,"tag":501,"props":8816,"children":8817},{"style":557},[8818],{"type":418,"value":8819},"  \n",{"type":413,"tag":501,"props":8821,"children":8822},{"class":503,"line":649},[8823,8828,8833],{"type":413,"tag":501,"props":8824,"children":8825},{"style":7436},[8826],{"type":418,"value":8827},"function",{"type":413,"tag":501,"props":8829,"children":8830},{"style":567},[8831],{"type":418,"value":8832}," CreateScope",{"type":413,"tag":501,"props":8834,"children":8835},{"style":519},[8836],{"type":418,"value":8837},"(\n",{"type":413,"tag":501,"props":8839,"children":8840},{"class":503,"line":659},[8841,8846,8850,8855,8859,8864],{"type":413,"tag":501,"props":8842,"children":8843},{"style":519},[8844],{"type":418,"value":8845},"    [",{"type":413,"tag":501,"props":8847,"children":8848},{"style":7436},[8849],{"type":418,"value":2502},{"type":413,"tag":501,"props":8851,"children":8852},{"style":519},[8853],{"type":418,"value":8854},"]",{"type":413,"tag":501,"props":8856,"children":8857},{"style":519},[8858],{"type":418,"value":8303},{"type":413,"tag":501,"props":8860,"children":8861},{"style":557},[8862],{"type":418,"value":8863},"value",{"type":413,"tag":501,"props":8865,"children":8866},{"style":519},[8867],{"type":418,"value":745},{"type":413,"tag":501,"props":8869,"children":8870},{"class":503,"line":716},[8871,8875,8879,8883,8887,8892],{"type":413,"tag":501,"props":8872,"children":8873},{"style":519},[8874],{"type":418,"value":8845},{"type":413,"tag":501,"props":8876,"children":8877},{"style":7436},[8878],{"type":418,"value":2502},{"type":413,"tag":501,"props":8880,"children":8881},{"style":519},[8882],{"type":418,"value":8854},{"type":413,"tag":501,"props":8884,"children":8885},{"style":519},[8886],{"type":418,"value":8303},{"type":413,"tag":501,"props":8888,"children":8889},{"style":557},[8890],{"type":418,"value":8891},"userConsentDisplayName",{"type":413,"tag":501,"props":8893,"children":8894},{"style":519},[8895],{"type":418,"value":745},{"type":413,"tag":501,"props":8897,"children":8898},{"class":503,"line":725},[8899,8903,8907,8911,8915,8920],{"type":413,"tag":501,"props":8900,"children":8901},{"style":519},[8902],{"type":418,"value":8845},{"type":413,"tag":501,"props":8904,"children":8905},{"style":7436},[8906],{"type":418,"value":2502},{"type":413,"tag":501,"props":8908,"children":8909},{"style":519},[8910],{"type":418,"value":8854},{"type":413,"tag":501,"props":8912,"children":8913},{"style":519},[8914],{"type":418,"value":8303},{"type":413,"tag":501,"props":8916,"children":8917},{"style":557},[8918],{"type":418,"value":8919},"userConsentDescription",{"type":413,"tag":501,"props":8921,"children":8922},{"style":519},[8923],{"type":418,"value":745},{"type":413,"tag":501,"props":8925,"children":8926},{"class":503,"line":748},[8927,8931,8935,8939,8943,8948],{"type":413,"tag":501,"props":8928,"children":8929},{"style":519},[8930],{"type":418,"value":8845},{"type":413,"tag":501,"props":8932,"children":8933},{"style":7436},[8934],{"type":418,"value":2502},{"type":413,"tag":501,"props":8936,"children":8937},{"style":519},[8938],{"type":418,"value":8854},{"type":413,"tag":501,"props":8940,"children":8941},{"style":519},[8942],{"type":418,"value":8303},{"type":413,"tag":501,"props":8944,"children":8945},{"style":557},[8946],{"type":418,"value":8947},"adminConsentDisplayName",{"type":413,"tag":501,"props":8949,"children":8950},{"style":519},[8951],{"type":418,"value":745},{"type":413,"tag":501,"props":8953,"children":8954},{"class":503,"line":769},[8955,8959,8963,8967,8971,8976],{"type":413,"tag":501,"props":8956,"children":8957},{"style":519},[8958],{"type":418,"value":8845},{"type":413,"tag":501,"props":8960,"children":8961},{"style":7436},[8962],{"type":418,"value":2502},{"type":413,"tag":501,"props":8964,"children":8965},{"style":519},[8966],{"type":418,"value":8854},{"type":413,"tag":501,"props":8968,"children":8969},{"style":519},[8970],{"type":418,"value":8303},{"type":413,"tag":501,"props":8972,"children":8973},{"style":557},[8974],{"type":418,"value":8975},"adminConsentDescription",{"type":413,"tag":501,"props":8977,"children":8978},{"style":519},[8979],{"type":418,"value":5814},{"type":413,"tag":501,"props":8981,"children":8982},{"class":503,"line":797},[8983],{"type":413,"tag":501,"props":8984,"children":8985},{"style":519},[8986],{"type":418,"value":722},{"type":413,"tag":501,"props":8988,"children":8989},{"class":503,"line":1145},[8990,8995,8999,9003,9007],{"type":413,"tag":501,"props":8991,"children":8992},{"style":519},[8993],{"type":418,"value":8994},"    $",{"type":413,"tag":501,"props":8996,"children":8997},{"style":557},[8998],{"type":418,"value":8525},{"type":413,"tag":501,"props":9000,"children":9001},{"style":519},[9002],{"type":418,"value":736},{"type":413,"tag":501,"props":9004,"children":9005},{"style":567},[9006],{"type":418,"value":8439},{"type":413,"tag":501,"props":9008,"children":9009},{"style":557},[9010],{"type":418,"value":9011}," Microsoft.Open.MsGraph.Model.PermissionScope\n",{"type":413,"tag":501,"props":9013,"children":9014},{"class":503,"line":1154},[9015,9019,9024,9028],{"type":413,"tag":501,"props":9016,"children":9017},{"style":519},[9018],{"type":418,"value":8994},{"type":413,"tag":501,"props":9020,"children":9021},{"style":557},[9022],{"type":418,"value":9023},"scope.Id ",{"type":413,"tag":501,"props":9025,"children":9026},{"style":519},[9027],{"type":418,"value":736},{"type":413,"tag":501,"props":9029,"children":9030},{"style":567},[9031],{"type":418,"value":9032}," New-Guid\n",{"type":413,"tag":501,"props":9034,"children":9035},{"class":503,"line":4568},[9036,9040,9045,9049,9053],{"type":413,"tag":501,"props":9037,"children":9038},{"style":519},[9039],{"type":418,"value":8994},{"type":413,"tag":501,"props":9041,"children":9042},{"style":557},[9043],{"type":418,"value":9044},"scope.Value ",{"type":413,"tag":501,"props":9046,"children":9047},{"style":519},[9048],{"type":418,"value":736},{"type":413,"tag":501,"props":9050,"children":9051},{"style":519},[9052],{"type":418,"value":8303},{"type":413,"tag":501,"props":9054,"children":9055},{"style":557},[9056],{"type":418,"value":9057},"value\n",{"type":413,"tag":501,"props":9059,"children":9060},{"class":503,"line":4577},[9061,9065,9070,9074,9078],{"type":413,"tag":501,"props":9062,"children":9063},{"style":519},[9064],{"type":418,"value":8994},{"type":413,"tag":501,"props":9066,"children":9067},{"style":557},[9068],{"type":418,"value":9069},"scope.UserConsentDisplayName ",{"type":413,"tag":501,"props":9071,"children":9072},{"style":519},[9073],{"type":418,"value":736},{"type":413,"tag":501,"props":9075,"children":9076},{"style":519},[9077],{"type":418,"value":8303},{"type":413,"tag":501,"props":9079,"children":9080},{"style":557},[9081],{"type":418,"value":9082},"userConsentDisplayName\n",{"type":413,"tag":501,"props":9084,"children":9085},{"class":503,"line":4591},[9086,9090,9095,9099,9103],{"type":413,"tag":501,"props":9087,"children":9088},{"style":519},[9089],{"type":418,"value":8994},{"type":413,"tag":501,"props":9091,"children":9092},{"style":557},[9093],{"type":418,"value":9094},"scope.UserConsentDescription ",{"type":413,"tag":501,"props":9096,"children":9097},{"style":519},[9098],{"type":418,"value":736},{"type":413,"tag":501,"props":9100,"children":9101},{"style":519},[9102],{"type":418,"value":8303},{"type":413,"tag":501,"props":9104,"children":9105},{"style":557},[9106],{"type":418,"value":9107},"userConsentDescription\n",{"type":413,"tag":501,"props":9109,"children":9110},{"class":503,"line":4600},[9111,9115,9120,9124,9128],{"type":413,"tag":501,"props":9112,"children":9113},{"style":519},[9114],{"type":418,"value":8994},{"type":413,"tag":501,"props":9116,"children":9117},{"style":557},[9118],{"type":418,"value":9119},"scope.AdminConsentDisplayName ",{"type":413,"tag":501,"props":9121,"children":9122},{"style":519},[9123],{"type":418,"value":736},{"type":413,"tag":501,"props":9125,"children":9126},{"style":519},[9127],{"type":418,"value":8303},{"type":413,"tag":501,"props":9129,"children":9130},{"style":557},[9131],{"type":418,"value":9132},"adminConsentDisplayName\n",{"type":413,"tag":501,"props":9134,"children":9135},{"class":503,"line":4630},[9136,9140,9145,9149,9153],{"type":413,"tag":501,"props":9137,"children":9138},{"style":519},[9139],{"type":418,"value":8994},{"type":413,"tag":501,"props":9141,"children":9142},{"style":557},[9143],{"type":418,"value":9144},"scope.AdminConsentDescription ",{"type":413,"tag":501,"props":9146,"children":9147},{"style":519},[9148],{"type":418,"value":736},{"type":413,"tag":501,"props":9150,"children":9151},{"style":519},[9152],{"type":418,"value":8303},{"type":413,"tag":501,"props":9154,"children":9155},{"style":557},[9156],{"type":418,"value":9157},"adminConsentDescription\n",{"type":413,"tag":501,"props":9159,"children":9160},{"class":503,"line":4660},[9161,9165,9170,9174],{"type":413,"tag":501,"props":9162,"children":9163},{"style":519},[9164],{"type":418,"value":8994},{"type":413,"tag":501,"props":9166,"children":9167},{"style":557},[9168],{"type":418,"value":9169},"scope.IsEnabled ",{"type":413,"tag":501,"props":9171,"children":9172},{"style":519},[9173],{"type":418,"value":736},{"type":413,"tag":501,"props":9175,"children":9176},{"style":519},[9177],{"type":418,"value":9178}," $true\n",{"type":413,"tag":501,"props":9180,"children":9181},{"class":503,"line":4669},[9182,9186,9191,9195,9199,9203],{"type":413,"tag":501,"props":9183,"children":9184},{"style":519},[9185],{"type":418,"value":8994},{"type":413,"tag":501,"props":9187,"children":9188},{"style":557},[9189],{"type":418,"value":9190},"scope.Type ",{"type":413,"tag":501,"props":9192,"children":9193},{"style":519},[9194],{"type":418,"value":736},{"type":413,"tag":501,"props":9196,"children":9197},{"style":519},[9198],{"type":418,"value":784},{"type":413,"tag":501,"props":9200,"children":9201},{"style":583},[9202],{"type":418,"value":1138},{"type":413,"tag":501,"props":9204,"children":9205},{"style":519},[9206],{"type":418,"value":794},{"type":413,"tag":501,"props":9208,"children":9209},{"class":503,"line":4681},[9210,9214,9218],{"type":413,"tag":501,"props":9211,"children":9212},{"style":1812},[9213],{"type":418,"value":1815},{"type":413,"tag":501,"props":9215,"children":9216},{"style":519},[9217],{"type":418,"value":8303},{"type":413,"tag":501,"props":9219,"children":9220},{"style":557},[9221],{"type":418,"value":9222},"scope\n",{"type":413,"tag":501,"props":9224,"children":9225},{"class":503,"line":4689},[9226],{"type":413,"tag":501,"props":9227,"children":9228},{"style":519},[9229],{"type":418,"value":2530},{"type":413,"tag":1556,"props":9231,"children":9233},{"id":9232},"preauthorize-teams-clients",[9234],{"type":418,"value":9235},"Preauthorize Teams clients.",{"type":413,"tag":414,"props":9237,"children":9238},{},[9239],{"type":418,"value":9240},"As the Teams clients will ask for a token with the previously created scope, they must be authorized to have access to this permission. That is what does the following script:",{"type":413,"tag":492,"props":9242,"children":9244},{"className":2689,"code":9243,"language":248,"meta":401,"style":401},"# Authorize Teams mobile/desktop client and Teams web client to access API\n$preAuthorizedApplications = New-Object 'System.Collections.Generic.List[Microsoft.Open.MSGraph.ModePreAuthorizedApplication]'\n$teamsRichClienPreauthorization = CreatePreAuthorizedApplication `\n    -applicationIdToPreAuthorize '1fec8e78-bce4-4aaf-ab1b-5451cc387264' `\n    -scopeId $scope.Id\n$teamsWebClienPreauthorization = CreatePreAuthorizedApplication `\n    -applicationIdToPreAuthorize '5e3ce6c0-2b1f-4285-8d4b-75ee78787346' `\n    -scopeId $scope.Id\n$preAuthorizedApplications.Add($teamsRichClienPreauthorization)\n$preAuthorizedApplications.Add($teamsWebClienPreauthorization)   \n$app = Get-AzureADMSApplication -ObjectId $applicationObjectId\n$app.Api.PreAuthorizedApplications = $preAuthorizedApplications\nSet-AzureADMSApplication -ObjectId $app.Id -Api $app.Api\n",[9245],{"type":413,"tag":443,"props":9246,"children":9247},{"__ignoreMap":401},[9248,9256,9290,9316,9346,9367,9391,9419,9438,9463,9492,9527,9552],{"type":413,"tag":501,"props":9249,"children":9250},{"class":503,"line":504},[9251],{"type":413,"tag":501,"props":9252,"children":9253},{"style":1766},[9254],{"type":418,"value":9255},"# Authorize Teams mobile/desktop client and Teams web client to access API\n",{"type":413,"tag":501,"props":9257,"children":9258},{"class":503,"line":540},[9259,9263,9268,9272,9276,9281,9286],{"type":413,"tag":501,"props":9260,"children":9261},{"style":519},[9262],{"type":418,"value":3293},{"type":413,"tag":501,"props":9264,"children":9265},{"style":557},[9266],{"type":418,"value":9267},"preAuthorizedApplications ",{"type":413,"tag":501,"props":9269,"children":9270},{"style":519},[9271],{"type":418,"value":736},{"type":413,"tag":501,"props":9273,"children":9274},{"style":567},[9275],{"type":418,"value":8439},{"type":413,"tag":501,"props":9277,"children":9278},{"style":519},[9279],{"type":418,"value":9280}," '",{"type":413,"tag":501,"props":9282,"children":9283},{"style":583},[9284],{"type":418,"value":9285},"System.Collections.Generic.List[Microsoft.Open.MSGraph.ModePreAuthorizedApplication]",{"type":413,"tag":501,"props":9287,"children":9288},{"style":519},[9289],{"type":418,"value":2845},{"type":413,"tag":501,"props":9291,"children":9292},{"class":503,"line":598},[9293,9297,9302,9306,9311],{"type":413,"tag":501,"props":9294,"children":9295},{"style":519},[9296],{"type":418,"value":3293},{"type":413,"tag":501,"props":9298,"children":9299},{"style":557},[9300],{"type":418,"value":9301},"teamsRichClienPreauthorization ",{"type":413,"tag":501,"props":9303,"children":9304},{"style":519},[9305],{"type":418,"value":736},{"type":413,"tag":501,"props":9307,"children":9308},{"style":557},[9309],{"type":418,"value":9310}," CreatePreAuthorizedApplication ",{"type":413,"tag":501,"props":9312,"children":9313},{"style":519},[9314],{"type":418,"value":9315},"`\n",{"type":413,"tag":501,"props":9317,"children":9318},{"class":503,"line":649},[9319,9323,9328,9332,9337,9341],{"type":413,"tag":501,"props":9320,"children":9321},{"style":519},[9322],{"type":418,"value":8568},{"type":413,"tag":501,"props":9324,"children":9325},{"style":557},[9326],{"type":418,"value":9327},"applicationIdToPreAuthorize ",{"type":413,"tag":501,"props":9329,"children":9330},{"style":519},[9331],{"type":418,"value":2835},{"type":413,"tag":501,"props":9333,"children":9334},{"style":583},[9335],{"type":418,"value":9336},"1fec8e78-bce4-4aaf-ab1b-5451cc387264",{"type":413,"tag":501,"props":9338,"children":9339},{"style":519},[9340],{"type":418,"value":2835},{"type":413,"tag":501,"props":9342,"children":9343},{"style":519},[9344],{"type":418,"value":9345}," `\n",{"type":413,"tag":501,"props":9347,"children":9348},{"class":503,"line":659},[9349,9353,9358,9362],{"type":413,"tag":501,"props":9350,"children":9351},{"style":519},[9352],{"type":418,"value":8568},{"type":413,"tag":501,"props":9354,"children":9355},{"style":557},[9356],{"type":418,"value":9357},"scopeId ",{"type":413,"tag":501,"props":9359,"children":9360},{"style":519},[9361],{"type":418,"value":3293},{"type":413,"tag":501,"props":9363,"children":9364},{"style":557},[9365],{"type":418,"value":9366},"scope.Id\n",{"type":413,"tag":501,"props":9368,"children":9369},{"class":503,"line":716},[9370,9374,9379,9383,9387],{"type":413,"tag":501,"props":9371,"children":9372},{"style":519},[9373],{"type":418,"value":3293},{"type":413,"tag":501,"props":9375,"children":9376},{"style":557},[9377],{"type":418,"value":9378},"teamsWebClienPreauthorization ",{"type":413,"tag":501,"props":9380,"children":9381},{"style":519},[9382],{"type":418,"value":736},{"type":413,"tag":501,"props":9384,"children":9385},{"style":557},[9386],{"type":418,"value":9310},{"type":413,"tag":501,"props":9388,"children":9389},{"style":519},[9390],{"type":418,"value":9315},{"type":413,"tag":501,"props":9392,"children":9393},{"class":503,"line":725},[9394,9398,9402,9406,9411,9415],{"type":413,"tag":501,"props":9395,"children":9396},{"style":519},[9397],{"type":418,"value":8568},{"type":413,"tag":501,"props":9399,"children":9400},{"style":557},[9401],{"type":418,"value":9327},{"type":413,"tag":501,"props":9403,"children":9404},{"style":519},[9405],{"type":418,"value":2835},{"type":413,"tag":501,"props":9407,"children":9408},{"style":583},[9409],{"type":418,"value":9410},"5e3ce6c0-2b1f-4285-8d4b-75ee78787346",{"type":413,"tag":501,"props":9412,"children":9413},{"style":519},[9414],{"type":418,"value":2835},{"type":413,"tag":501,"props":9416,"children":9417},{"style":519},[9418],{"type":418,"value":9345},{"type":413,"tag":501,"props":9420,"children":9421},{"class":503,"line":748},[9422,9426,9430,9434],{"type":413,"tag":501,"props":9423,"children":9424},{"style":519},[9425],{"type":418,"value":8568},{"type":413,"tag":501,"props":9427,"children":9428},{"style":557},[9429],{"type":418,"value":9357},{"type":413,"tag":501,"props":9431,"children":9432},{"style":519},[9433],{"type":418,"value":3293},{"type":413,"tag":501,"props":9435,"children":9436},{"style":557},[9437],{"type":418,"value":9366},{"type":413,"tag":501,"props":9439,"children":9440},{"class":503,"line":769},[9441,9445,9450,9454,9459],{"type":413,"tag":501,"props":9442,"children":9443},{"style":519},[9444],{"type":418,"value":3293},{"type":413,"tag":501,"props":9446,"children":9447},{"style":557},[9448],{"type":418,"value":9449},"preAuthorizedApplications.Add",{"type":413,"tag":501,"props":9451,"children":9452},{"style":519},[9453],{"type":418,"value":8499},{"type":413,"tag":501,"props":9455,"children":9456},{"style":557},[9457],{"type":418,"value":9458},"teamsRichClienPreauthorization",{"type":413,"tag":501,"props":9460,"children":9461},{"style":519},[9462],{"type":418,"value":5814},{"type":413,"tag":501,"props":9464,"children":9465},{"class":503,"line":797},[9466,9470,9474,9478,9483,9487],{"type":413,"tag":501,"props":9467,"children":9468},{"style":519},[9469],{"type":418,"value":3293},{"type":413,"tag":501,"props":9471,"children":9472},{"style":557},[9473],{"type":418,"value":9449},{"type":413,"tag":501,"props":9475,"children":9476},{"style":519},[9477],{"type":418,"value":8499},{"type":413,"tag":501,"props":9479,"children":9480},{"style":557},[9481],{"type":418,"value":9482},"teamsWebClienPreauthorization",{"type":413,"tag":501,"props":9484,"children":9485},{"style":519},[9486],{"type":418,"value":5503},{"type":413,"tag":501,"props":9488,"children":9489},{"style":557},[9490],{"type":418,"value":9491},"   \n",{"type":413,"tag":501,"props":9493,"children":9494},{"class":503,"line":1145},[9495,9499,9503,9507,9511,9515,9519,9523],{"type":413,"tag":501,"props":9496,"children":9497},{"style":519},[9498],{"type":418,"value":3293},{"type":413,"tag":501,"props":9500,"children":9501},{"style":557},[9502],{"type":418,"value":8111},{"type":413,"tag":501,"props":9504,"children":9505},{"style":519},[9506],{"type":418,"value":736},{"type":413,"tag":501,"props":9508,"children":9509},{"style":567},[9510],{"type":418,"value":8120},{"type":413,"tag":501,"props":9512,"children":9513},{"style":519},[9514],{"type":418,"value":2758},{"type":413,"tag":501,"props":9516,"children":9517},{"style":557},[9518],{"type":418,"value":8129},{"type":413,"tag":501,"props":9520,"children":9521},{"style":519},[9522],{"type":418,"value":3293},{"type":413,"tag":501,"props":9524,"children":9525},{"style":557},[9526],{"type":418,"value":8138},{"type":413,"tag":501,"props":9528,"children":9529},{"class":503,"line":1154},[9530,9534,9539,9543,9547],{"type":413,"tag":501,"props":9531,"children":9532},{"style":519},[9533],{"type":418,"value":3293},{"type":413,"tag":501,"props":9535,"children":9536},{"style":557},[9537],{"type":418,"value":9538},"app.Api.PreAuthorizedApplications ",{"type":413,"tag":501,"props":9540,"children":9541},{"style":519},[9542],{"type":418,"value":736},{"type":413,"tag":501,"props":9544,"children":9545},{"style":519},[9546],{"type":418,"value":8303},{"type":413,"tag":501,"props":9548,"children":9549},{"style":557},[9550],{"type":418,"value":9551},"preAuthorizedApplications\n",{"type":413,"tag":501,"props":9553,"children":9554},{"class":503,"line":4568},[9555,9559,9563,9567,9571,9575,9579,9583,9587],{"type":413,"tag":501,"props":9556,"children":9557},{"style":567},[9558],{"type":418,"value":8316},{"type":413,"tag":501,"props":9560,"children":9561},{"style":519},[9562],{"type":418,"value":2758},{"type":413,"tag":501,"props":9564,"children":9565},{"style":557},[9566],{"type":418,"value":8129},{"type":413,"tag":501,"props":9568,"children":9569},{"style":519},[9570],{"type":418,"value":3293},{"type":413,"tag":501,"props":9572,"children":9573},{"style":557},[9574],{"type":418,"value":8333},{"type":413,"tag":501,"props":9576,"children":9577},{"style":519},[9578],{"type":418,"value":2707},{"type":413,"tag":501,"props":9580,"children":9581},{"style":557},[9582],{"type":418,"value":8753},{"type":413,"tag":501,"props":9584,"children":9585},{"style":519},[9586],{"type":418,"value":3293},{"type":413,"tag":501,"props":9588,"children":9589},{"style":557},[9590],{"type":418,"value":8762},{"type":413,"tag":414,"props":9592,"children":9593},{},[9594],{"type":418,"value":9595},"This code calls a PowerShell function that simply creates the PreAuthorizedApplication object.",{"type":413,"tag":492,"props":9597,"children":9599},{"className":2689,"code":9598,"language":248,"meta":401,"style":401},"\u003C#.Description\n   This function creates a new PreAuthorized application on a specified scope\n#>  \nfunction CreatePreAuthorizedApplication(\n    [string] $applicationIdToPreAuthorize,\n    [string] $scopeId)\n{\n    $preAuthorizedApplication = New-Object 'Microsoft.Open.MSGraph.Model.PreAuthorizedApplication'\n    $preAuthorizedApplication.AppId = $applicationIdToPreAuthorize\n    $preAuthorizedApplication.DelegatedPermissionIds = @($scopeId)\n    return $preAuthorizedApplication\n}\n",[9600],{"type":413,"tag":443,"props":9601,"children":9602},{"__ignoreMap":401},[9603,9618,9626,9637,9653,9681,9709,9716,9749,9774,9807,9823],{"type":413,"tag":501,"props":9604,"children":9605},{"class":503,"line":504},[9606,9610,9614],{"type":413,"tag":501,"props":9607,"children":9608},{"style":1766},[9609],{"type":418,"value":8789},{"type":413,"tag":501,"props":9611,"children":9612},{"style":1766},[9613],{"type":418,"value":564},{"type":413,"tag":501,"props":9615,"children":9616},{"style":1812},[9617],{"type":418,"value":8798},{"type":413,"tag":501,"props":9619,"children":9620},{"class":503,"line":540},[9621],{"type":413,"tag":501,"props":9622,"children":9623},{"style":1766},[9624],{"type":418,"value":9625},"   This function creates a new PreAuthorized application on a specified scope\n",{"type":413,"tag":501,"props":9627,"children":9628},{"class":503,"line":598},[9629,9633],{"type":413,"tag":501,"props":9630,"children":9631},{"style":1766},[9632],{"type":418,"value":8814},{"type":413,"tag":501,"props":9634,"children":9635},{"style":557},[9636],{"type":418,"value":8819},{"type":413,"tag":501,"props":9638,"children":9639},{"class":503,"line":649},[9640,9644,9649],{"type":413,"tag":501,"props":9641,"children":9642},{"style":7436},[9643],{"type":418,"value":8827},{"type":413,"tag":501,"props":9645,"children":9646},{"style":567},[9647],{"type":418,"value":9648}," CreatePreAuthorizedApplication",{"type":413,"tag":501,"props":9650,"children":9651},{"style":519},[9652],{"type":418,"value":8837},{"type":413,"tag":501,"props":9654,"children":9655},{"class":503,"line":659},[9656,9660,9664,9668,9672,9677],{"type":413,"tag":501,"props":9657,"children":9658},{"style":519},[9659],{"type":418,"value":8845},{"type":413,"tag":501,"props":9661,"children":9662},{"style":7436},[9663],{"type":418,"value":2502},{"type":413,"tag":501,"props":9665,"children":9666},{"style":519},[9667],{"type":418,"value":8854},{"type":413,"tag":501,"props":9669,"children":9670},{"style":519},[9671],{"type":418,"value":8303},{"type":413,"tag":501,"props":9673,"children":9674},{"style":557},[9675],{"type":418,"value":9676},"applicationIdToPreAuthorize",{"type":413,"tag":501,"props":9678,"children":9679},{"style":519},[9680],{"type":418,"value":745},{"type":413,"tag":501,"props":9682,"children":9683},{"class":503,"line":716},[9684,9688,9692,9696,9700,9705],{"type":413,"tag":501,"props":9685,"children":9686},{"style":519},[9687],{"type":418,"value":8845},{"type":413,"tag":501,"props":9689,"children":9690},{"style":7436},[9691],{"type":418,"value":2502},{"type":413,"tag":501,"props":9693,"children":9694},{"style":519},[9695],{"type":418,"value":8854},{"type":413,"tag":501,"props":9697,"children":9698},{"style":519},[9699],{"type":418,"value":8303},{"type":413,"tag":501,"props":9701,"children":9702},{"style":557},[9703],{"type":418,"value":9704},"scopeId",{"type":413,"tag":501,"props":9706,"children":9707},{"style":519},[9708],{"type":418,"value":5814},{"type":413,"tag":501,"props":9710,"children":9711},{"class":503,"line":725},[9712],{"type":413,"tag":501,"props":9713,"children":9714},{"style":519},[9715],{"type":418,"value":722},{"type":413,"tag":501,"props":9717,"children":9718},{"class":503,"line":748},[9719,9723,9728,9732,9736,9740,9745],{"type":413,"tag":501,"props":9720,"children":9721},{"style":519},[9722],{"type":418,"value":8994},{"type":413,"tag":501,"props":9724,"children":9725},{"style":557},[9726],{"type":418,"value":9727},"preAuthorizedApplication ",{"type":413,"tag":501,"props":9729,"children":9730},{"style":519},[9731],{"type":418,"value":736},{"type":413,"tag":501,"props":9733,"children":9734},{"style":567},[9735],{"type":418,"value":8439},{"type":413,"tag":501,"props":9737,"children":9738},{"style":519},[9739],{"type":418,"value":9280},{"type":413,"tag":501,"props":9741,"children":9742},{"style":583},[9743],{"type":418,"value":9744},"Microsoft.Open.MSGraph.Model.PreAuthorizedApplication",{"type":413,"tag":501,"props":9746,"children":9747},{"style":519},[9748],{"type":418,"value":2845},{"type":413,"tag":501,"props":9750,"children":9751},{"class":503,"line":769},[9752,9756,9761,9765,9769],{"type":413,"tag":501,"props":9753,"children":9754},{"style":519},[9755],{"type":418,"value":8994},{"type":413,"tag":501,"props":9757,"children":9758},{"style":557},[9759],{"type":418,"value":9760},"preAuthorizedApplication.AppId ",{"type":413,"tag":501,"props":9762,"children":9763},{"style":519},[9764],{"type":418,"value":736},{"type":413,"tag":501,"props":9766,"children":9767},{"style":519},[9768],{"type":418,"value":8303},{"type":413,"tag":501,"props":9770,"children":9771},{"style":557},[9772],{"type":418,"value":9773},"applicationIdToPreAuthorize\n",{"type":413,"tag":501,"props":9775,"children":9776},{"class":503,"line":797},[9777,9781,9786,9790,9795,9799,9803],{"type":413,"tag":501,"props":9778,"children":9779},{"style":519},[9780],{"type":418,"value":8994},{"type":413,"tag":501,"props":9782,"children":9783},{"style":557},[9784],{"type":418,"value":9785},"preAuthorizedApplication.DelegatedPermissionIds ",{"type":413,"tag":501,"props":9787,"children":9788},{"style":519},[9789],{"type":418,"value":736},{"type":413,"tag":501,"props":9791,"children":9792},{"style":1402},[9793],{"type":418,"value":9794}," @",{"type":413,"tag":501,"props":9796,"children":9797},{"style":519},[9798],{"type":418,"value":8499},{"type":413,"tag":501,"props":9800,"children":9801},{"style":557},[9802],{"type":418,"value":9704},{"type":413,"tag":501,"props":9804,"children":9805},{"style":519},[9806],{"type":418,"value":5814},{"type":413,"tag":501,"props":9808,"children":9809},{"class":503,"line":1145},[9810,9814,9818],{"type":413,"tag":501,"props":9811,"children":9812},{"style":1812},[9813],{"type":418,"value":1815},{"type":413,"tag":501,"props":9815,"children":9816},{"style":519},[9817],{"type":418,"value":8303},{"type":413,"tag":501,"props":9819,"children":9820},{"style":557},[9821],{"type":418,"value":9822},"preAuthorizedApplication\n",{"type":413,"tag":501,"props":9824,"children":9825},{"class":503,"line":1154},[9826],{"type":413,"tag":501,"props":9827,"children":9828},{"style":519},[9829],{"type":418,"value":2530},{"type":413,"tag":1556,"props":9831,"children":9833},{"id":9832},"grant-user-level-graph-api-permissions",[9834],{"type":418,"value":9835},"Grant user-level Graph API permissions",{"type":413,"tag":414,"props":9837,"children":9838},{},[9839,9841,9848],{"type":418,"value":9840},"The next step consists in specifying the permissions the application will need for the AAD endpoint: email, offline_access, openid, profile (",{"type":413,"tag":432,"props":9842,"children":9845},{"href":9843,"rel":9844},"https://docs.microsoft.com/fr-fr/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes",[436],[9846],{"type":418,"value":9847},"OpenID connect scopes",{"type":418,"value":9849},").",{"type":413,"tag":492,"props":9851,"children":9853},{"className":2689,"code":9852,"language":248,"meta":401,"style":401},"# Add API permissions needed\n$requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.MsGraph.Model.RequiredResourceAccess]\n$requiredPermissions = GetRequiredPermissions `\n    -applicationDisplayName 'Microsoft Graph' `\n    -requiredDelegatedPermissions \"User.Read|email|offline_access|openid|profile\"\n$requiredResourcesAccess.Add($requiredPermissions)   \nSet-AzureADMSApplication -ObjectId $app.Id -RequiredResourceAccess $requiredPermissions\n",[9854],{"type":413,"tag":443,"props":9855,"children":9856},{"__ignoreMap":401},[9857,9865,9902,9927,9956,9981,10010],{"type":413,"tag":501,"props":9858,"children":9859},{"class":503,"line":504},[9860],{"type":413,"tag":501,"props":9861,"children":9862},{"style":1766},[9863],{"type":418,"value":9864},"# Add API permissions needed\n",{"type":413,"tag":501,"props":9866,"children":9867},{"class":503,"line":540},[9868,9872,9877,9881,9885,9889,9893,9898],{"type":413,"tag":501,"props":9869,"children":9870},{"style":519},[9871],{"type":418,"value":3293},{"type":413,"tag":501,"props":9873,"children":9874},{"style":557},[9875],{"type":418,"value":9876},"requiredResourcesAccess ",{"type":413,"tag":501,"props":9878,"children":9879},{"style":519},[9880],{"type":418,"value":736},{"type":413,"tag":501,"props":9882,"children":9883},{"style":567},[9884],{"type":418,"value":8439},{"type":413,"tag":501,"props":9886,"children":9887},{"style":557},[9888],{"type":418,"value":8444},{"type":413,"tag":501,"props":9890,"children":9891},{"style":519},[9892],{"type":418,"value":8449},{"type":413,"tag":501,"props":9894,"children":9895},{"style":7436},[9896],{"type":418,"value":9897},"Microsoft.Open.MsGraph.Model.RequiredResourceAccess",{"type":413,"tag":501,"props":9899,"children":9900},{"style":519},[9901],{"type":418,"value":8459},{"type":413,"tag":501,"props":9903,"children":9904},{"class":503,"line":598},[9905,9909,9914,9918,9923],{"type":413,"tag":501,"props":9906,"children":9907},{"style":519},[9908],{"type":418,"value":3293},{"type":413,"tag":501,"props":9910,"children":9911},{"style":557},[9912],{"type":418,"value":9913},"requiredPermissions ",{"type":413,"tag":501,"props":9915,"children":9916},{"style":519},[9917],{"type":418,"value":736},{"type":413,"tag":501,"props":9919,"children":9920},{"style":557},[9921],{"type":418,"value":9922}," GetRequiredPermissions ",{"type":413,"tag":501,"props":9924,"children":9925},{"style":519},[9926],{"type":418,"value":9315},{"type":413,"tag":501,"props":9928,"children":9929},{"class":503,"line":649},[9930,9934,9939,9943,9948,9952],{"type":413,"tag":501,"props":9931,"children":9932},{"style":519},[9933],{"type":418,"value":8568},{"type":413,"tag":501,"props":9935,"children":9936},{"style":557},[9937],{"type":418,"value":9938},"applicationDisplayName ",{"type":413,"tag":501,"props":9940,"children":9941},{"style":519},[9942],{"type":418,"value":2835},{"type":413,"tag":501,"props":9944,"children":9945},{"style":583},[9946],{"type":418,"value":9947},"Microsoft Graph",{"type":413,"tag":501,"props":9949,"children":9950},{"style":519},[9951],{"type":418,"value":2835},{"type":413,"tag":501,"props":9953,"children":9954},{"style":519},[9955],{"type":418,"value":9345},{"type":413,"tag":501,"props":9957,"children":9958},{"class":503,"line":659},[9959,9963,9968,9972,9977],{"type":413,"tag":501,"props":9960,"children":9961},{"style":519},[9962],{"type":418,"value":8568},{"type":413,"tag":501,"props":9964,"children":9965},{"style":557},[9966],{"type":418,"value":9967},"requiredDelegatedPermissions ",{"type":413,"tag":501,"props":9969,"children":9970},{"style":519},[9971],{"type":418,"value":580},{"type":413,"tag":501,"props":9973,"children":9974},{"style":583},[9975],{"type":418,"value":9976},"User.Read|email|offline_access|openid|profile",{"type":413,"tag":501,"props":9978,"children":9979},{"style":519},[9980],{"type":418,"value":794},{"type":413,"tag":501,"props":9982,"children":9983},{"class":503,"line":716},[9984,9988,9993,9997,10002,10006],{"type":413,"tag":501,"props":9985,"children":9986},{"style":519},[9987],{"type":418,"value":3293},{"type":413,"tag":501,"props":9989,"children":9990},{"style":557},[9991],{"type":418,"value":9992},"requiredResourcesAccess.Add",{"type":413,"tag":501,"props":9994,"children":9995},{"style":519},[9996],{"type":418,"value":8499},{"type":413,"tag":501,"props":9998,"children":9999},{"style":557},[10000],{"type":418,"value":10001},"requiredPermissions",{"type":413,"tag":501,"props":10003,"children":10004},{"style":519},[10005],{"type":418,"value":5503},{"type":413,"tag":501,"props":10007,"children":10008},{"style":557},[10009],{"type":418,"value":9491},{"type":413,"tag":501,"props":10011,"children":10012},{"class":503,"line":725},[10013,10017,10021,10025,10029,10033,10037,10042,10046],{"type":413,"tag":501,"props":10014,"children":10015},{"style":567},[10016],{"type":418,"value":8316},{"type":413,"tag":501,"props":10018,"children":10019},{"style":519},[10020],{"type":418,"value":2758},{"type":413,"tag":501,"props":10022,"children":10023},{"style":557},[10024],{"type":418,"value":8129},{"type":413,"tag":501,"props":10026,"children":10027},{"style":519},[10028],{"type":418,"value":3293},{"type":413,"tag":501,"props":10030,"children":10031},{"style":557},[10032],{"type":418,"value":8333},{"type":413,"tag":501,"props":10034,"children":10035},{"style":519},[10036],{"type":418,"value":2707},{"type":413,"tag":501,"props":10038,"children":10039},{"style":557},[10040],{"type":418,"value":10041},"RequiredResourceAccess ",{"type":413,"tag":501,"props":10043,"children":10044},{"style":519},[10045],{"type":418,"value":3293},{"type":413,"tag":501,"props":10047,"children":10048},{"style":557},[10049],{"type":418,"value":10050},"requiredPermissions\n",{"type":413,"tag":414,"props":10052,"children":10053},{},[10054,10056,10062],{"type":418,"value":10055},"This code calls a PowerShell function ",{"type":413,"tag":443,"props":10057,"children":10059},{"className":10058},[],[10060],{"type":418,"value":10061},"GetRequiredPermissions",{"type":418,"value":10063}," that add the delegated or application permissions specified in parameter. Here we only ask for delegated permissions of Microsoft Graph needed to retrieve an OpenId Connect token but this function is generic and could be used to require scopes or roles of other APIs.",{"type":413,"tag":492,"props":10065,"children":10067},{"className":2689,"code":10066,"language":248,"meta":401,"style":401},"# Example: GetRequiredPermissions \"Microsoft Graph\"  \"Graph.Read|User.Read\"\n# See also: http://stackoverflow.com/questions/42164581/how-to-configure-a-new-azure-ad-application-through-powershell\nfunction GetRequiredPermissions(\n    [string] $applicationDisplayName,\n    [string] $requiredDelegatedPermissions,\n    [string]$requiredApplicationPermissions,\n    $servicePrincipal)\n{\n    # If we are passed the service principal we use it directly, otherwise we find it from the display name (which might not be unique)\n    if ($servicePrincipal)\n    {\n        $sp = $servicePrincipal\n    }\n    else\n    {\n        $sp = Get-AzureADServicePrincipal -Filter \"DisplayName eq '$applicationDisplayName'\"\n    }\n\n    $requiredAccess = New-Object Microsoft.Open.MsGraph.Model.RequiredResourceAccess\n    $requiredAccess.ResourceAppId = $sp.AppId \n    $requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.MsGraph.Model.ResourceAccess]\n\n    # $sp.Oauth2Permissions | Select Id,AdminConsentDisplayName,Value: To see the list of all the Delegated permissions for the application:\n    if ($requiredDelegatedPermissions)\n    {\n        AddResourcePermission $requiredAccess -exposedPermissions $sp.Oauth2Permissions -requiredAccesses $requiredDelegatedPermissions -permissionType \"Scope\"\n    }\n    \n    # $sp.AppRoles | Select Id,AdminConsentDisplayName,Value: To see the list of all the Application permissions for the application\n    if ($requiredApplicationPermissions)\n    {\n        AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType \"Role\"\n    }\n    return $requiredAccess\n}\n",[10068],{"type":413,"tag":443,"props":10069,"children":10070},{"__ignoreMap":401},[10071,10079,10087,10103,10131,10159,10184,10200,10207,10215,10236,10243,10269,10276,10284,10291,10345,10352,10359,10384,10409,10446,10453,10461,10480,10487,10560,10567,10575,10583,10602,10609,10679,10686,10702],{"type":413,"tag":501,"props":10072,"children":10073},{"class":503,"line":504},[10074],{"type":413,"tag":501,"props":10075,"children":10076},{"style":1766},[10077],{"type":418,"value":10078},"# Example: GetRequiredPermissions \"Microsoft Graph\"  \"Graph.Read|User.Read\"\n",{"type":413,"tag":501,"props":10080,"children":10081},{"class":503,"line":540},[10082],{"type":413,"tag":501,"props":10083,"children":10084},{"style":1766},[10085],{"type":418,"value":10086},"# See also: http://stackoverflow.com/questions/42164581/how-to-configure-a-new-azure-ad-application-through-powershell\n",{"type":413,"tag":501,"props":10088,"children":10089},{"class":503,"line":598},[10090,10094,10099],{"type":413,"tag":501,"props":10091,"children":10092},{"style":7436},[10093],{"type":418,"value":8827},{"type":413,"tag":501,"props":10095,"children":10096},{"style":567},[10097],{"type":418,"value":10098}," GetRequiredPermissions",{"type":413,"tag":501,"props":10100,"children":10101},{"style":519},[10102],{"type":418,"value":8837},{"type":413,"tag":501,"props":10104,"children":10105},{"class":503,"line":649},[10106,10110,10114,10118,10122,10127],{"type":413,"tag":501,"props":10107,"children":10108},{"style":519},[10109],{"type":418,"value":8845},{"type":413,"tag":501,"props":10111,"children":10112},{"style":7436},[10113],{"type":418,"value":2502},{"type":413,"tag":501,"props":10115,"children":10116},{"style":519},[10117],{"type":418,"value":8854},{"type":413,"tag":501,"props":10119,"children":10120},{"style":519},[10121],{"type":418,"value":8303},{"type":413,"tag":501,"props":10123,"children":10124},{"style":557},[10125],{"type":418,"value":10126},"applicationDisplayName",{"type":413,"tag":501,"props":10128,"children":10129},{"style":519},[10130],{"type":418,"value":745},{"type":413,"tag":501,"props":10132,"children":10133},{"class":503,"line":659},[10134,10138,10142,10146,10150,10155],{"type":413,"tag":501,"props":10135,"children":10136},{"style":519},[10137],{"type":418,"value":8845},{"type":413,"tag":501,"props":10139,"children":10140},{"style":7436},[10141],{"type":418,"value":2502},{"type":413,"tag":501,"props":10143,"children":10144},{"style":519},[10145],{"type":418,"value":8854},{"type":413,"tag":501,"props":10147,"children":10148},{"style":519},[10149],{"type":418,"value":8303},{"type":413,"tag":501,"props":10151,"children":10152},{"style":557},[10153],{"type":418,"value":10154},"requiredDelegatedPermissions",{"type":413,"tag":501,"props":10156,"children":10157},{"style":519},[10158],{"type":418,"value":745},{"type":413,"tag":501,"props":10160,"children":10161},{"class":503,"line":716},[10162,10166,10170,10175,10180],{"type":413,"tag":501,"props":10163,"children":10164},{"style":519},[10165],{"type":418,"value":8845},{"type":413,"tag":501,"props":10167,"children":10168},{"style":7436},[10169],{"type":418,"value":2502},{"type":413,"tag":501,"props":10171,"children":10172},{"style":519},[10173],{"type":418,"value":10174},"]$",{"type":413,"tag":501,"props":10176,"children":10177},{"style":557},[10178],{"type":418,"value":10179},"requiredApplicationPermissions",{"type":413,"tag":501,"props":10181,"children":10182},{"style":519},[10183],{"type":418,"value":745},{"type":413,"tag":501,"props":10185,"children":10186},{"class":503,"line":725},[10187,10191,10196],{"type":413,"tag":501,"props":10188,"children":10189},{"style":519},[10190],{"type":418,"value":8994},{"type":413,"tag":501,"props":10192,"children":10193},{"style":557},[10194],{"type":418,"value":10195},"servicePrincipal",{"type":413,"tag":501,"props":10197,"children":10198},{"style":519},[10199],{"type":418,"value":5814},{"type":413,"tag":501,"props":10201,"children":10202},{"class":503,"line":748},[10203],{"type":413,"tag":501,"props":10204,"children":10205},{"style":519},[10206],{"type":418,"value":722},{"type":413,"tag":501,"props":10208,"children":10209},{"class":503,"line":769},[10210],{"type":413,"tag":501,"props":10211,"children":10212},{"style":1766},[10213],{"type":418,"value":10214},"    # If we are passed the service principal we use it directly, otherwise we find it from the display name (which might not be unique)\n",{"type":413,"tag":501,"props":10216,"children":10217},{"class":503,"line":797},[10218,10223,10228,10232],{"type":413,"tag":501,"props":10219,"children":10220},{"style":1812},[10221],{"type":418,"value":10222},"    if",{"type":413,"tag":501,"props":10224,"children":10225},{"style":519},[10226],{"type":418,"value":10227}," ($",{"type":413,"tag":501,"props":10229,"children":10230},{"style":557},[10231],{"type":418,"value":10195},{"type":413,"tag":501,"props":10233,"children":10234},{"style":519},[10235],{"type":418,"value":5814},{"type":413,"tag":501,"props":10237,"children":10238},{"class":503,"line":1145},[10239],{"type":413,"tag":501,"props":10240,"children":10241},{"style":519},[10242],{"type":418,"value":1002},{"type":413,"tag":501,"props":10244,"children":10245},{"class":503,"line":1154},[10246,10251,10256,10260,10264],{"type":413,"tag":501,"props":10247,"children":10248},{"style":519},[10249],{"type":418,"value":10250},"        $",{"type":413,"tag":501,"props":10252,"children":10253},{"style":557},[10254],{"type":418,"value":10255},"sp ",{"type":413,"tag":501,"props":10257,"children":10258},{"style":519},[10259],{"type":418,"value":736},{"type":413,"tag":501,"props":10261,"children":10262},{"style":519},[10263],{"type":418,"value":8303},{"type":413,"tag":501,"props":10265,"children":10266},{"style":557},[10267],{"type":418,"value":10268},"servicePrincipal\n",{"type":413,"tag":501,"props":10270,"children":10271},{"class":503,"line":4568},[10272],{"type":413,"tag":501,"props":10273,"children":10274},{"style":519},[10275],{"type":418,"value":1356},{"type":413,"tag":501,"props":10277,"children":10278},{"class":503,"line":4577},[10279],{"type":413,"tag":501,"props":10280,"children":10281},{"style":1812},[10282],{"type":418,"value":10283},"    else\n",{"type":413,"tag":501,"props":10285,"children":10286},{"class":503,"line":4591},[10287],{"type":413,"tag":501,"props":10288,"children":10289},{"style":519},[10290],{"type":418,"value":1002},{"type":413,"tag":501,"props":10292,"children":10293},{"class":503,"line":4600},[10294,10298,10302,10306,10311,10315,10320,10324,10329,10333,10337,10341],{"type":413,"tag":501,"props":10295,"children":10296},{"style":519},[10297],{"type":418,"value":10250},{"type":413,"tag":501,"props":10299,"children":10300},{"style":557},[10301],{"type":418,"value":10255},{"type":413,"tag":501,"props":10303,"children":10304},{"style":519},[10305],{"type":418,"value":736},{"type":413,"tag":501,"props":10307,"children":10308},{"style":567},[10309],{"type":418,"value":10310}," Get-AzureADServicePrincipal",{"type":413,"tag":501,"props":10312,"children":10313},{"style":519},[10314],{"type":418,"value":2758},{"type":413,"tag":501,"props":10316,"children":10317},{"style":557},[10318],{"type":418,"value":10319},"Filter ",{"type":413,"tag":501,"props":10321,"children":10322},{"style":519},[10323],{"type":418,"value":580},{"type":413,"tag":501,"props":10325,"children":10326},{"style":583},[10327],{"type":418,"value":10328},"DisplayName eq '",{"type":413,"tag":501,"props":10330,"children":10331},{"style":519},[10332],{"type":418,"value":3293},{"type":413,"tag":501,"props":10334,"children":10335},{"style":557},[10336],{"type":418,"value":10126},{"type":413,"tag":501,"props":10338,"children":10339},{"style":583},[10340],{"type":418,"value":2835},{"type":413,"tag":501,"props":10342,"children":10343},{"style":519},[10344],{"type":418,"value":794},{"type":413,"tag":501,"props":10346,"children":10347},{"class":503,"line":4630},[10348],{"type":413,"tag":501,"props":10349,"children":10350},{"style":519},[10351],{"type":418,"value":1356},{"type":413,"tag":501,"props":10353,"children":10354},{"class":503,"line":4660},[10355],{"type":413,"tag":501,"props":10356,"children":10357},{"emptyLinePlaceholder":653},[10358],{"type":418,"value":656},{"type":413,"tag":501,"props":10360,"children":10361},{"class":503,"line":4669},[10362,10366,10371,10375,10379],{"type":413,"tag":501,"props":10363,"children":10364},{"style":519},[10365],{"type":418,"value":8994},{"type":413,"tag":501,"props":10367,"children":10368},{"style":557},[10369],{"type":418,"value":10370},"requiredAccess ",{"type":413,"tag":501,"props":10372,"children":10373},{"style":519},[10374],{"type":418,"value":736},{"type":413,"tag":501,"props":10376,"children":10377},{"style":567},[10378],{"type":418,"value":8439},{"type":413,"tag":501,"props":10380,"children":10381},{"style":557},[10382],{"type":418,"value":10383}," Microsoft.Open.MsGraph.Model.RequiredResourceAccess\n",{"type":413,"tag":501,"props":10385,"children":10386},{"class":503,"line":4681},[10387,10391,10396,10400,10404],{"type":413,"tag":501,"props":10388,"children":10389},{"style":519},[10390],{"type":418,"value":8994},{"type":413,"tag":501,"props":10392,"children":10393},{"style":557},[10394],{"type":418,"value":10395},"requiredAccess.ResourceAppId ",{"type":413,"tag":501,"props":10397,"children":10398},{"style":519},[10399],{"type":418,"value":736},{"type":413,"tag":501,"props":10401,"children":10402},{"style":519},[10403],{"type":418,"value":8303},{"type":413,"tag":501,"props":10405,"children":10406},{"style":557},[10407],{"type":418,"value":10408},"sp.AppId \n",{"type":413,"tag":501,"props":10410,"children":10411},{"class":503,"line":4689},[10412,10416,10421,10425,10429,10433,10437,10442],{"type":413,"tag":501,"props":10413,"children":10414},{"style":519},[10415],{"type":418,"value":8994},{"type":413,"tag":501,"props":10417,"children":10418},{"style":557},[10419],{"type":418,"value":10420},"requiredAccess.ResourceAccess ",{"type":413,"tag":501,"props":10422,"children":10423},{"style":519},[10424],{"type":418,"value":736},{"type":413,"tag":501,"props":10426,"children":10427},{"style":567},[10428],{"type":418,"value":8439},{"type":413,"tag":501,"props":10430,"children":10431},{"style":557},[10432],{"type":418,"value":8444},{"type":413,"tag":501,"props":10434,"children":10435},{"style":519},[10436],{"type":418,"value":8449},{"type":413,"tag":501,"props":10438,"children":10439},{"style":7436},[10440],{"type":418,"value":10441},"Microsoft.Open.MsGraph.Model.ResourceAccess",{"type":413,"tag":501,"props":10443,"children":10444},{"style":519},[10445],{"type":418,"value":8459},{"type":413,"tag":501,"props":10447,"children":10448},{"class":503,"line":4718},[10449],{"type":413,"tag":501,"props":10450,"children":10451},{"emptyLinePlaceholder":653},[10452],{"type":418,"value":656},{"type":413,"tag":501,"props":10454,"children":10455},{"class":503,"line":4746},[10456],{"type":413,"tag":501,"props":10457,"children":10458},{"style":1766},[10459],{"type":418,"value":10460},"    # $sp.Oauth2Permissions | Select Id,AdminConsentDisplayName,Value: To see the list of all the Delegated permissions for the application:\n",{"type":413,"tag":501,"props":10462,"children":10463},{"class":503,"line":4754},[10464,10468,10472,10476],{"type":413,"tag":501,"props":10465,"children":10466},{"style":1812},[10467],{"type":418,"value":10222},{"type":413,"tag":501,"props":10469,"children":10470},{"style":519},[10471],{"type":418,"value":10227},{"type":413,"tag":501,"props":10473,"children":10474},{"style":557},[10475],{"type":418,"value":10154},{"type":413,"tag":501,"props":10477,"children":10478},{"style":519},[10479],{"type":418,"value":5814},{"type":413,"tag":501,"props":10481,"children":10482},{"class":503,"line":4766},[10483],{"type":413,"tag":501,"props":10484,"children":10485},{"style":519},[10486],{"type":418,"value":1002},{"type":413,"tag":501,"props":10488,"children":10489},{"class":503,"line":4774},[10490,10495,10499,10503,10507,10512,10516,10521,10525,10530,10534,10538,10542,10547,10551,10556],{"type":413,"tag":501,"props":10491,"children":10492},{"style":557},[10493],{"type":418,"value":10494},"        AddResourcePermission ",{"type":413,"tag":501,"props":10496,"children":10497},{"style":519},[10498],{"type":418,"value":3293},{"type":413,"tag":501,"props":10500,"children":10501},{"style":557},[10502],{"type":418,"value":10370},{"type":413,"tag":501,"props":10504,"children":10505},{"style":519},[10506],{"type":418,"value":2707},{"type":413,"tag":501,"props":10508,"children":10509},{"style":557},[10510],{"type":418,"value":10511},"exposedPermissions ",{"type":413,"tag":501,"props":10513,"children":10514},{"style":519},[10515],{"type":418,"value":3293},{"type":413,"tag":501,"props":10517,"children":10518},{"style":557},[10519],{"type":418,"value":10520},"sp.Oauth2Permissions ",{"type":413,"tag":501,"props":10522,"children":10523},{"style":519},[10524],{"type":418,"value":2707},{"type":413,"tag":501,"props":10526,"children":10527},{"style":557},[10528],{"type":418,"value":10529},"requiredAccesses ",{"type":413,"tag":501,"props":10531,"children":10532},{"style":519},[10533],{"type":418,"value":3293},{"type":413,"tag":501,"props":10535,"children":10536},{"style":557},[10537],{"type":418,"value":9967},{"type":413,"tag":501,"props":10539,"children":10540},{"style":519},[10541],{"type":418,"value":2707},{"type":413,"tag":501,"props":10543,"children":10544},{"style":557},[10545],{"type":418,"value":10546},"permissionType ",{"type":413,"tag":501,"props":10548,"children":10549},{"style":519},[10550],{"type":418,"value":580},{"type":413,"tag":501,"props":10552,"children":10553},{"style":583},[10554],{"type":418,"value":10555},"Scope",{"type":413,"tag":501,"props":10557,"children":10558},{"style":519},[10559],{"type":418,"value":794},{"type":413,"tag":501,"props":10561,"children":10562},{"class":503,"line":4803},[10563],{"type":413,"tag":501,"props":10564,"children":10565},{"style":519},[10566],{"type":418,"value":1356},{"type":413,"tag":501,"props":10568,"children":10569},{"class":503,"line":4828},[10570],{"type":413,"tag":501,"props":10571,"children":10572},{"style":557},[10573],{"type":418,"value":10574},"    \n",{"type":413,"tag":501,"props":10576,"children":10577},{"class":503,"line":4836},[10578],{"type":413,"tag":501,"props":10579,"children":10580},{"style":1766},[10581],{"type":418,"value":10582},"    # $sp.AppRoles | Select Id,AdminConsentDisplayName,Value: To see the list of all the Application permissions for the application\n",{"type":413,"tag":501,"props":10584,"children":10585},{"class":503,"line":4848},[10586,10590,10594,10598],{"type":413,"tag":501,"props":10587,"children":10588},{"style":1812},[10589],{"type":418,"value":10222},{"type":413,"tag":501,"props":10591,"children":10592},{"style":519},[10593],{"type":418,"value":10227},{"type":413,"tag":501,"props":10595,"children":10596},{"style":557},[10597],{"type":418,"value":10179},{"type":413,"tag":501,"props":10599,"children":10600},{"style":519},[10601],{"type":418,"value":5814},{"type":413,"tag":501,"props":10603,"children":10604},{"class":503,"line":4856},[10605],{"type":413,"tag":501,"props":10606,"children":10607},{"style":519},[10608],{"type":418,"value":1002},{"type":413,"tag":501,"props":10610,"children":10611},{"class":503,"line":4884},[10612,10616,10620,10624,10628,10632,10636,10641,10645,10649,10653,10658,10662,10666,10670,10675],{"type":413,"tag":501,"props":10613,"children":10614},{"style":557},[10615],{"type":418,"value":10494},{"type":413,"tag":501,"props":10617,"children":10618},{"style":519},[10619],{"type":418,"value":3293},{"type":413,"tag":501,"props":10621,"children":10622},{"style":557},[10623],{"type":418,"value":10370},{"type":413,"tag":501,"props":10625,"children":10626},{"style":519},[10627],{"type":418,"value":2707},{"type":413,"tag":501,"props":10629,"children":10630},{"style":557},[10631],{"type":418,"value":10511},{"type":413,"tag":501,"props":10633,"children":10634},{"style":519},[10635],{"type":418,"value":3293},{"type":413,"tag":501,"props":10637,"children":10638},{"style":557},[10639],{"type":418,"value":10640},"sp.AppRoles ",{"type":413,"tag":501,"props":10642,"children":10643},{"style":519},[10644],{"type":418,"value":2707},{"type":413,"tag":501,"props":10646,"children":10647},{"style":557},[10648],{"type":418,"value":10529},{"type":413,"tag":501,"props":10650,"children":10651},{"style":519},[10652],{"type":418,"value":3293},{"type":413,"tag":501,"props":10654,"children":10655},{"style":557},[10656],{"type":418,"value":10657},"requiredApplicationPermissions ",{"type":413,"tag":501,"props":10659,"children":10660},{"style":519},[10661],{"type":418,"value":2707},{"type":413,"tag":501,"props":10663,"children":10664},{"style":557},[10665],{"type":418,"value":10546},{"type":413,"tag":501,"props":10667,"children":10668},{"style":519},[10669],{"type":418,"value":580},{"type":413,"tag":501,"props":10671,"children":10672},{"style":583},[10673],{"type":418,"value":10674},"Role",{"type":413,"tag":501,"props":10676,"children":10677},{"style":519},[10678],{"type":418,"value":794},{"type":413,"tag":501,"props":10680,"children":10681},{"class":503,"line":4909},[10682],{"type":413,"tag":501,"props":10683,"children":10684},{"style":519},[10685],{"type":418,"value":1356},{"type":413,"tag":501,"props":10687,"children":10688},{"class":503,"line":4918},[10689,10693,10697],{"type":413,"tag":501,"props":10690,"children":10691},{"style":1812},[10692],{"type":418,"value":1815},{"type":413,"tag":501,"props":10694,"children":10695},{"style":519},[10696],{"type":418,"value":8303},{"type":413,"tag":501,"props":10698,"children":10699},{"style":557},[10700],{"type":418,"value":10701},"requiredAccess\n",{"type":413,"tag":501,"props":10703,"children":10704},{"class":503,"line":4927},[10705],{"type":413,"tag":501,"props":10706,"children":10707},{"style":519},[10708],{"type":418,"value":2530},{"type":413,"tag":414,"props":10710,"children":10711},{},[10712,10713,10718,10720,10726],{"type":418,"value":2679},{"type":413,"tag":443,"props":10714,"children":10716},{"className":10715},[],[10717],{"type":418,"value":10061},{"type":418,"value":10719}," function calls a ",{"type":413,"tag":443,"props":10721,"children":10723},{"className":10722},[],[10724],{"type":418,"value":10725},"AddResourcePermission",{"type":418,"value":10727}," function that creates permissions (ResourceAccess objects).",{"type":413,"tag":492,"props":10729,"children":10731},{"className":2689,"code":10730,"language":248,"meta":401,"style":401},"# Adds the requiredAccesses (expressed as a pipe separated string) to the requiredAccess structure\n# The exposed permissions are in the $exposedPermissions collection, and the type of permission (Scope | Role) is \n# described in $permissionType\nfunction AddResourcePermission(\n    $requiredAccess,\n    $exposedPermissions,\n    [string]$requiredAccesses,\n    [string]$permissionType)\n{\n        foreach($permission in $requiredAccesses.Trim().Split(\"|\"))\n        {\n            foreach($exposedPermission in $exposedPermissions)\n            {\n                if ($exposedPermission.Value -eq $permission)\n                {\n                    $resourceAccess = New-Object Microsoft.Open.MsGraph.Model.ResourceAccess\n                    $resourceAccess.Type = $permissionType # Scope = Delegated permissions | Role = Application permissions\n                    $resourceAccess.Id = $exposedPermission.Id # Read directory data\n                    $requiredAccess.ResourceAccess.Add($resourceAccess)\n                }\n            }\n        }\n}\n",[10732],{"type":413,"tag":443,"props":10733,"children":10734},{"__ignoreMap":401},[10735,10743,10751,10759,10775,10791,10807,10831,10855,10862,10924,10931,10964,10971,11006,11014,11040,11069,11099,11124,11132,11139,11147],{"type":413,"tag":501,"props":10736,"children":10737},{"class":503,"line":504},[10738],{"type":413,"tag":501,"props":10739,"children":10740},{"style":1766},[10741],{"type":418,"value":10742},"# Adds the requiredAccesses (expressed as a pipe separated string) to the requiredAccess structure\n",{"type":413,"tag":501,"props":10744,"children":10745},{"class":503,"line":540},[10746],{"type":413,"tag":501,"props":10747,"children":10748},{"style":1766},[10749],{"type":418,"value":10750},"# The exposed permissions are in the $exposedPermissions collection, and the type of permission (Scope | Role) is \n",{"type":413,"tag":501,"props":10752,"children":10753},{"class":503,"line":598},[10754],{"type":413,"tag":501,"props":10755,"children":10756},{"style":1766},[10757],{"type":418,"value":10758},"# described in $permissionType\n",{"type":413,"tag":501,"props":10760,"children":10761},{"class":503,"line":649},[10762,10766,10771],{"type":413,"tag":501,"props":10763,"children":10764},{"style":7436},[10765],{"type":418,"value":8827},{"type":413,"tag":501,"props":10767,"children":10768},{"style":567},[10769],{"type":418,"value":10770}," AddResourcePermission",{"type":413,"tag":501,"props":10772,"children":10773},{"style":519},[10774],{"type":418,"value":8837},{"type":413,"tag":501,"props":10776,"children":10777},{"class":503,"line":659},[10778,10782,10787],{"type":413,"tag":501,"props":10779,"children":10780},{"style":519},[10781],{"type":418,"value":8994},{"type":413,"tag":501,"props":10783,"children":10784},{"style":557},[10785],{"type":418,"value":10786},"requiredAccess",{"type":413,"tag":501,"props":10788,"children":10789},{"style":519},[10790],{"type":418,"value":745},{"type":413,"tag":501,"props":10792,"children":10793},{"class":503,"line":716},[10794,10798,10803],{"type":413,"tag":501,"props":10795,"children":10796},{"style":519},[10797],{"type":418,"value":8994},{"type":413,"tag":501,"props":10799,"children":10800},{"style":557},[10801],{"type":418,"value":10802},"exposedPermissions",{"type":413,"tag":501,"props":10804,"children":10805},{"style":519},[10806],{"type":418,"value":745},{"type":413,"tag":501,"props":10808,"children":10809},{"class":503,"line":725},[10810,10814,10818,10822,10827],{"type":413,"tag":501,"props":10811,"children":10812},{"style":519},[10813],{"type":418,"value":8845},{"type":413,"tag":501,"props":10815,"children":10816},{"style":7436},[10817],{"type":418,"value":2502},{"type":413,"tag":501,"props":10819,"children":10820},{"style":519},[10821],{"type":418,"value":10174},{"type":413,"tag":501,"props":10823,"children":10824},{"style":557},[10825],{"type":418,"value":10826},"requiredAccesses",{"type":413,"tag":501,"props":10828,"children":10829},{"style":519},[10830],{"type":418,"value":745},{"type":413,"tag":501,"props":10832,"children":10833},{"class":503,"line":748},[10834,10838,10842,10846,10851],{"type":413,"tag":501,"props":10835,"children":10836},{"style":519},[10837],{"type":418,"value":8845},{"type":413,"tag":501,"props":10839,"children":10840},{"style":7436},[10841],{"type":418,"value":2502},{"type":413,"tag":501,"props":10843,"children":10844},{"style":519},[10845],{"type":418,"value":10174},{"type":413,"tag":501,"props":10847,"children":10848},{"style":557},[10849],{"type":418,"value":10850},"permissionType",{"type":413,"tag":501,"props":10852,"children":10853},{"style":519},[10854],{"type":418,"value":5814},{"type":413,"tag":501,"props":10856,"children":10857},{"class":503,"line":769},[10858],{"type":413,"tag":501,"props":10859,"children":10860},{"style":519},[10861],{"type":418,"value":722},{"type":413,"tag":501,"props":10863,"children":10864},{"class":503,"line":797},[10865,10870,10874,10879,10884,10888,10893,10898,10903,10907,10911,10915,10919],{"type":413,"tag":501,"props":10866,"children":10867},{"style":1812},[10868],{"type":418,"value":10869},"        foreach",{"type":413,"tag":501,"props":10871,"children":10872},{"style":519},[10873],{"type":418,"value":8499},{"type":413,"tag":501,"props":10875,"children":10876},{"style":557},[10877],{"type":418,"value":10878},"permission ",{"type":413,"tag":501,"props":10880,"children":10881},{"style":1812},[10882],{"type":418,"value":10883},"in",{"type":413,"tag":501,"props":10885,"children":10886},{"style":519},[10887],{"type":418,"value":8303},{"type":413,"tag":501,"props":10889,"children":10890},{"style":557},[10891],{"type":418,"value":10892},"requiredAccesses.Trim",{"type":413,"tag":501,"props":10894,"children":10895},{"style":519},[10896],{"type":418,"value":10897},"()",{"type":413,"tag":501,"props":10899,"children":10900},{"style":557},[10901],{"type":418,"value":10902},".Split",{"type":413,"tag":501,"props":10904,"children":10905},{"style":519},[10906],{"type":418,"value":575},{"type":413,"tag":501,"props":10908,"children":10909},{"style":519},[10910],{"type":418,"value":580},{"type":413,"tag":501,"props":10912,"children":10913},{"style":583},[10914],{"type":418,"value":8476},{"type":413,"tag":501,"props":10916,"children":10917},{"style":519},[10918],{"type":418,"value":580},{"type":413,"tag":501,"props":10920,"children":10921},{"style":519},[10922],{"type":418,"value":10923},"))\n",{"type":413,"tag":501,"props":10925,"children":10926},{"class":503,"line":1145},[10927],{"type":413,"tag":501,"props":10928,"children":10929},{"style":519},[10930],{"type":418,"value":4574},{"type":413,"tag":501,"props":10932,"children":10933},{"class":503,"line":1154},[10934,10939,10943,10948,10952,10956,10960],{"type":413,"tag":501,"props":10935,"children":10936},{"style":1812},[10937],{"type":418,"value":10938},"            foreach",{"type":413,"tag":501,"props":10940,"children":10941},{"style":519},[10942],{"type":418,"value":8499},{"type":413,"tag":501,"props":10944,"children":10945},{"style":557},[10946],{"type":418,"value":10947},"exposedPermission ",{"type":413,"tag":501,"props":10949,"children":10950},{"style":1812},[10951],{"type":418,"value":10883},{"type":413,"tag":501,"props":10953,"children":10954},{"style":519},[10955],{"type":418,"value":8303},{"type":413,"tag":501,"props":10957,"children":10958},{"style":557},[10959],{"type":418,"value":10802},{"type":413,"tag":501,"props":10961,"children":10962},{"style":519},[10963],{"type":418,"value":5814},{"type":413,"tag":501,"props":10965,"children":10966},{"class":503,"line":4568},[10967],{"type":413,"tag":501,"props":10968,"children":10969},{"style":519},[10970],{"type":418,"value":4597},{"type":413,"tag":501,"props":10972,"children":10973},{"class":503,"line":4577},[10974,10979,10983,10988,10993,10997,11002],{"type":413,"tag":501,"props":10975,"children":10976},{"style":1812},[10977],{"type":418,"value":10978},"                if",{"type":413,"tag":501,"props":10980,"children":10981},{"style":519},[10982],{"type":418,"value":10227},{"type":413,"tag":501,"props":10984,"children":10985},{"style":557},[10986],{"type":418,"value":10987},"exposedPermission.Value ",{"type":413,"tag":501,"props":10989,"children":10990},{"style":519},[10991],{"type":418,"value":10992},"-eq",{"type":413,"tag":501,"props":10994,"children":10995},{"style":519},[10996],{"type":418,"value":8303},{"type":413,"tag":501,"props":10998,"children":10999},{"style":557},[11000],{"type":418,"value":11001},"permission",{"type":413,"tag":501,"props":11003,"children":11004},{"style":519},[11005],{"type":418,"value":5814},{"type":413,"tag":501,"props":11007,"children":11008},{"class":503,"line":4591},[11009],{"type":413,"tag":501,"props":11010,"children":11011},{"style":519},[11012],{"type":418,"value":11013},"                {\n",{"type":413,"tag":501,"props":11015,"children":11016},{"class":503,"line":4600},[11017,11022,11027,11031,11035],{"type":413,"tag":501,"props":11018,"children":11019},{"style":519},[11020],{"type":418,"value":11021},"                    $",{"type":413,"tag":501,"props":11023,"children":11024},{"style":557},[11025],{"type":418,"value":11026},"resourceAccess ",{"type":413,"tag":501,"props":11028,"children":11029},{"style":519},[11030],{"type":418,"value":736},{"type":413,"tag":501,"props":11032,"children":11033},{"style":567},[11034],{"type":418,"value":8439},{"type":413,"tag":501,"props":11036,"children":11037},{"style":557},[11038],{"type":418,"value":11039}," Microsoft.Open.MsGraph.Model.ResourceAccess\n",{"type":413,"tag":501,"props":11041,"children":11042},{"class":503,"line":4630},[11043,11047,11052,11056,11060,11064],{"type":413,"tag":501,"props":11044,"children":11045},{"style":519},[11046],{"type":418,"value":11021},{"type":413,"tag":501,"props":11048,"children":11049},{"style":557},[11050],{"type":418,"value":11051},"resourceAccess.Type ",{"type":413,"tag":501,"props":11053,"children":11054},{"style":519},[11055],{"type":418,"value":736},{"type":413,"tag":501,"props":11057,"children":11058},{"style":519},[11059],{"type":418,"value":8303},{"type":413,"tag":501,"props":11061,"children":11062},{"style":557},[11063],{"type":418,"value":10546},{"type":413,"tag":501,"props":11065,"children":11066},{"style":1766},[11067],{"type":418,"value":11068},"# Scope = Delegated permissions | Role = Application permissions\n",{"type":413,"tag":501,"props":11070,"children":11071},{"class":503,"line":4660},[11072,11076,11081,11085,11089,11094],{"type":413,"tag":501,"props":11073,"children":11074},{"style":519},[11075],{"type":418,"value":11021},{"type":413,"tag":501,"props":11077,"children":11078},{"style":557},[11079],{"type":418,"value":11080},"resourceAccess.Id ",{"type":413,"tag":501,"props":11082,"children":11083},{"style":519},[11084],{"type":418,"value":736},{"type":413,"tag":501,"props":11086,"children":11087},{"style":519},[11088],{"type":418,"value":8303},{"type":413,"tag":501,"props":11090,"children":11091},{"style":557},[11092],{"type":418,"value":11093},"exposedPermission.Id ",{"type":413,"tag":501,"props":11095,"children":11096},{"style":1766},[11097],{"type":418,"value":11098},"# Read directory data\n",{"type":413,"tag":501,"props":11100,"children":11101},{"class":503,"line":4669},[11102,11106,11111,11115,11120],{"type":413,"tag":501,"props":11103,"children":11104},{"style":519},[11105],{"type":418,"value":11021},{"type":413,"tag":501,"props":11107,"children":11108},{"style":557},[11109],{"type":418,"value":11110},"requiredAccess.ResourceAccess.Add",{"type":413,"tag":501,"props":11112,"children":11113},{"style":519},[11114],{"type":418,"value":8499},{"type":413,"tag":501,"props":11116,"children":11117},{"style":557},[11118],{"type":418,"value":11119},"resourceAccess",{"type":413,"tag":501,"props":11121,"children":11122},{"style":519},[11123],{"type":418,"value":5814},{"type":413,"tag":501,"props":11125,"children":11126},{"class":503,"line":4681},[11127],{"type":413,"tag":501,"props":11128,"children":11129},{"style":519},[11130],{"type":418,"value":11131},"                }\n",{"type":413,"tag":501,"props":11133,"children":11134},{"class":503,"line":4689},[11135],{"type":413,"tag":501,"props":11136,"children":11137},{"style":519},[11138],{"type":418,"value":4915},{"type":413,"tag":501,"props":11140,"children":11141},{"class":503,"line":4718},[11142],{"type":413,"tag":501,"props":11143,"children":11144},{"style":519},[11145],{"type":418,"value":11146},"        }\n",{"type":413,"tag":501,"props":11148,"children":11149},{"class":503,"line":4746},[11150],{"type":413,"tag":501,"props":11151,"children":11152},{"style":519},[11153],{"type":418,"value":2530},{"type":413,"tag":420,"props":11155,"children":11157},{"id":11156},"using-the-script-in-an-azure-pipeline",[11158],{"type":418,"value":11159},"Using the script in an Azure Pipeline",{"type":413,"tag":414,"props":11161,"children":11162},{},[11163,11165,11172],{"type":418,"value":11164},"To execute this script in the Azure pipeline that deploys and configures the rest of the application infrastructure we can use an ",{"type":413,"tag":432,"props":11166,"children":11169},{"href":11167,"rel":11168},"https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-powershell?view=azure-devops",[436],[11170],{"type":418,"value":11171},"Azure PowerShell task",{"type":418,"value":564},{"type":413,"tag":414,"props":11174,"children":11175},{},[11176],{"type":418,"value":11177},"The task of the Azure Pipeline will look like this:",{"type":413,"tag":492,"props":11179,"children":11183},{"className":11180,"code":11181,"language":11182,"meta":401,"style":401},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","- task: AzurePowerShell@5\n  displayName: 'Configure Teams tab SSO'\n  inputs:\n    azureSubscription: 'My Azure Service Connection'\n    ScriptType: 'FilePath'\n    ScriptPath: 'infra/AdditionalScripts/ConfigureTeamsTabSSO.ps1'\n    ScriptArguments: \n      -applicationObjectId $(AzureAdObjectId) `\n      -customDomainName $(CustomDomainName)\n    azurePowerShellVersion: 'LatestVersion'\n","yaml",[11184],{"type":413,"tag":443,"props":11185,"children":11186},{"__ignoreMap":401},[11187,11209,11234,11247,11272,11297,11322,11338,11346,11354],{"type":413,"tag":501,"props":11188,"children":11189},{"class":503,"line":504},[11190,11194,11200,11204],{"type":413,"tag":501,"props":11191,"children":11192},{"style":519},[11193],{"type":418,"value":2707},{"type":413,"tag":501,"props":11195,"children":11197},{"style":11196},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[11198],{"type":418,"value":11199}," task",{"type":413,"tag":501,"props":11201,"children":11202},{"style":519},[11203],{"type":418,"value":6171},{"type":413,"tag":501,"props":11205,"children":11206},{"style":583},[11207],{"type":418,"value":11208}," AzurePowerShell@5\n",{"type":413,"tag":501,"props":11210,"children":11211},{"class":503,"line":540},[11212,11217,11221,11225,11230],{"type":413,"tag":501,"props":11213,"children":11214},{"style":11196},[11215],{"type":418,"value":11216},"  displayName",{"type":413,"tag":501,"props":11218,"children":11219},{"style":519},[11220],{"type":418,"value":6171},{"type":413,"tag":501,"props":11222,"children":11223},{"style":519},[11224],{"type":418,"value":9280},{"type":413,"tag":501,"props":11226,"children":11227},{"style":583},[11228],{"type":418,"value":11229},"Configure Teams tab SSO",{"type":413,"tag":501,"props":11231,"children":11232},{"style":519},[11233],{"type":418,"value":2845},{"type":413,"tag":501,"props":11235,"children":11236},{"class":503,"line":598},[11237,11242],{"type":413,"tag":501,"props":11238,"children":11239},{"style":11196},[11240],{"type":418,"value":11241},"  inputs",{"type":413,"tag":501,"props":11243,"children":11244},{"style":519},[11245],{"type":418,"value":11246},":\n",{"type":413,"tag":501,"props":11248,"children":11249},{"class":503,"line":649},[11250,11255,11259,11263,11268],{"type":413,"tag":501,"props":11251,"children":11252},{"style":11196},[11253],{"type":418,"value":11254},"    azureSubscription",{"type":413,"tag":501,"props":11256,"children":11257},{"style":519},[11258],{"type":418,"value":6171},{"type":413,"tag":501,"props":11260,"children":11261},{"style":519},[11262],{"type":418,"value":9280},{"type":413,"tag":501,"props":11264,"children":11265},{"style":583},[11266],{"type":418,"value":11267},"My Azure Service Connection",{"type":413,"tag":501,"props":11269,"children":11270},{"style":519},[11271],{"type":418,"value":2845},{"type":413,"tag":501,"props":11273,"children":11274},{"class":503,"line":659},[11275,11280,11284,11288,11293],{"type":413,"tag":501,"props":11276,"children":11277},{"style":11196},[11278],{"type":418,"value":11279},"    ScriptType",{"type":413,"tag":501,"props":11281,"children":11282},{"style":519},[11283],{"type":418,"value":6171},{"type":413,"tag":501,"props":11285,"children":11286},{"style":519},[11287],{"type":418,"value":9280},{"type":413,"tag":501,"props":11289,"children":11290},{"style":583},[11291],{"type":418,"value":11292},"FilePath",{"type":413,"tag":501,"props":11294,"children":11295},{"style":519},[11296],{"type":418,"value":2845},{"type":413,"tag":501,"props":11298,"children":11299},{"class":503,"line":716},[11300,11305,11309,11313,11318],{"type":413,"tag":501,"props":11301,"children":11302},{"style":11196},[11303],{"type":418,"value":11304},"    ScriptPath",{"type":413,"tag":501,"props":11306,"children":11307},{"style":519},[11308],{"type":418,"value":6171},{"type":413,"tag":501,"props":11310,"children":11311},{"style":519},[11312],{"type":418,"value":9280},{"type":413,"tag":501,"props":11314,"children":11315},{"style":583},[11316],{"type":418,"value":11317},"infra/AdditionalScripts/ConfigureTeamsTabSSO.ps1",{"type":413,"tag":501,"props":11319,"children":11320},{"style":519},[11321],{"type":418,"value":2845},{"type":413,"tag":501,"props":11323,"children":11324},{"class":503,"line":725},[11325,11330,11334],{"type":413,"tag":501,"props":11326,"children":11327},{"style":11196},[11328],{"type":418,"value":11329},"    ScriptArguments",{"type":413,"tag":501,"props":11331,"children":11332},{"style":519},[11333],{"type":418,"value":6171},{"type":413,"tag":501,"props":11335,"children":11336},{"style":557},[11337],{"type":418,"value":1806},{"type":413,"tag":501,"props":11339,"children":11340},{"class":503,"line":748},[11341],{"type":413,"tag":501,"props":11342,"children":11343},{"style":583},[11344],{"type":418,"value":11345},"      -applicationObjectId $(AzureAdObjectId) `\n",{"type":413,"tag":501,"props":11347,"children":11348},{"class":503,"line":769},[11349],{"type":413,"tag":501,"props":11350,"children":11351},{"style":583},[11352],{"type":418,"value":11353},"      -customDomainName $(CustomDomainName)\n",{"type":413,"tag":501,"props":11355,"children":11356},{"class":503,"line":797},[11357,11362,11366,11370,11375],{"type":413,"tag":501,"props":11358,"children":11359},{"style":11196},[11360],{"type":418,"value":11361},"    azurePowerShellVersion",{"type":413,"tag":501,"props":11363,"children":11364},{"style":519},[11365],{"type":418,"value":6171},{"type":413,"tag":501,"props":11367,"children":11368},{"style":519},[11369],{"type":418,"value":9280},{"type":413,"tag":501,"props":11371,"children":11372},{"style":583},[11373],{"type":418,"value":11374},"LatestVersion",{"type":413,"tag":501,"props":11376,"children":11377},{"style":519},[11378],{"type":418,"value":2845},{"type":413,"tag":414,"props":11380,"children":11381},{},[11382,11384,11389,11391,11398],{"type":418,"value":11383},"The advantage is that this task will connect to Azure with an Azure Service Connection that has enough rights to execute the Azure AD commands in this script. However, it involves passing to the ",{"type":413,"tag":443,"props":11385,"children":11387},{"className":11386},[],[11388],{"type":418,"value":8058},{"type":418,"value":11390}," command the access token of the Service Principal associated with the Azure Service Connection. This can easily be done as I found out in ",{"type":413,"tag":432,"props":11392,"children":11395},{"href":11393,"rel":11394},"https://stackoverflow.com/questions/60185213/automate-connect-azuread-using-powershell-in-azure-devops",[436],[11396],{"type":418,"value":11397},"a StackOverflow post",{"type":418,"value":564},{"type":413,"tag":492,"props":11400,"children":11402},{"className":2689,"code":11401,"language":248,"meta":401,"style":401},"$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext\n$graphToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, \"https://graph.microsoft.com\").AccessToken\n$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, \"https://graph.windows.net\").AccessToken\nConnect-AzureAD -AadAccessToken $aadToken -MsAccessToken $graphToken -AccountId $context.Account.Id -TenantId $context.tenant.id\n",[11403],{"type":413,"tag":443,"props":11404,"children":11405},{"__ignoreMap":401},[11406,11441,11568,11685],{"type":413,"tag":501,"props":11407,"children":11408},{"class":503,"line":504},[11409,11413,11418,11422,11427,11432,11436],{"type":413,"tag":501,"props":11410,"children":11411},{"style":519},[11412],{"type":418,"value":3293},{"type":413,"tag":501,"props":11414,"children":11415},{"style":557},[11416],{"type":418,"value":11417},"context ",{"type":413,"tag":501,"props":11419,"children":11420},{"style":519},[11421],{"type":418,"value":736},{"type":413,"tag":501,"props":11423,"children":11424},{"style":519},[11425],{"type":418,"value":11426}," [",{"type":413,"tag":501,"props":11428,"children":11429},{"style":7436},[11430],{"type":418,"value":11431},"Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider",{"type":413,"tag":501,"props":11433,"children":11434},{"style":519},[11435],{"type":418,"value":8854},{"type":413,"tag":501,"props":11437,"children":11438},{"style":557},[11439],{"type":418,"value":11440},"::Instance.Profile.DefaultContext\n",{"type":413,"tag":501,"props":11442,"children":11443},{"class":503,"line":540},[11444,11448,11453,11457,11461,11466,11470,11475,11479,11484,11488,11492,11497,11501,11505,11510,11515,11520,11524,11529,11533,11538,11542,11546,11550,11555,11559,11563],{"type":413,"tag":501,"props":11445,"children":11446},{"style":519},[11447],{"type":418,"value":3293},{"type":413,"tag":501,"props":11449,"children":11450},{"style":557},[11451],{"type":418,"value":11452},"graphToken ",{"type":413,"tag":501,"props":11454,"children":11455},{"style":519},[11456],{"type":418,"value":736},{"type":413,"tag":501,"props":11458,"children":11459},{"style":519},[11460],{"type":418,"value":11426},{"type":413,"tag":501,"props":11462,"children":11463},{"style":7436},[11464],{"type":418,"value":11465},"Microsoft.Azure.Commands.Common.Authentication.AzureSession",{"type":413,"tag":501,"props":11467,"children":11468},{"style":519},[11469],{"type":418,"value":8854},{"type":413,"tag":501,"props":11471,"children":11472},{"style":557},[11473],{"type":418,"value":11474},"::Instance.AuthenticationFactory.Authenticate",{"type":413,"tag":501,"props":11476,"children":11477},{"style":519},[11478],{"type":418,"value":8499},{"type":413,"tag":501,"props":11480,"children":11481},{"style":557},[11482],{"type":418,"value":11483},"context.Account",{"type":413,"tag":501,"props":11485,"children":11486},{"style":519},[11487],{"type":418,"value":704},{"type":413,"tag":501,"props":11489,"children":11490},{"style":519},[11491],{"type":418,"value":8303},{"type":413,"tag":501,"props":11493,"children":11494},{"style":557},[11495],{"type":418,"value":11496},"context.Environment",{"type":413,"tag":501,"props":11498,"children":11499},{"style":519},[11500],{"type":418,"value":704},{"type":413,"tag":501,"props":11502,"children":11503},{"style":519},[11504],{"type":418,"value":8303},{"type":413,"tag":501,"props":11506,"children":11507},{"style":557},[11508],{"type":418,"value":11509},"context.Tenant.Id.ToString",{"type":413,"tag":501,"props":11511,"children":11512},{"style":519},[11513],{"type":418,"value":11514},"(),",{"type":413,"tag":501,"props":11516,"children":11517},{"style":519},[11518],{"type":418,"value":11519}," $null,",{"type":413,"tag":501,"props":11521,"children":11522},{"style":519},[11523],{"type":418,"value":11426},{"type":413,"tag":501,"props":11525,"children":11526},{"style":7436},[11527],{"type":418,"value":11528},"Microsoft.Azure.Commands.Common.Authentication.ShowDialog",{"type":413,"tag":501,"props":11530,"children":11531},{"style":519},[11532],{"type":418,"value":8854},{"type":413,"tag":501,"props":11534,"children":11535},{"style":557},[11536],{"type":418,"value":11537},"::Never",{"type":413,"tag":501,"props":11539,"children":11540},{"style":519},[11541],{"type":418,"value":704},{"type":413,"tag":501,"props":11543,"children":11544},{"style":519},[11545],{"type":418,"value":11519},{"type":413,"tag":501,"props":11547,"children":11548},{"style":519},[11549],{"type":418,"value":784},{"type":413,"tag":501,"props":11551,"children":11552},{"style":583},[11553],{"type":418,"value":11554},"https://graph.microsoft.com",{"type":413,"tag":501,"props":11556,"children":11557},{"style":519},[11558],{"type":418,"value":580},{"type":413,"tag":501,"props":11560,"children":11561},{"style":519},[11562],{"type":418,"value":5503},{"type":413,"tag":501,"props":11564,"children":11565},{"style":557},[11566],{"type":418,"value":11567},".AccessToken\n",{"type":413,"tag":501,"props":11569,"children":11570},{"class":503,"line":598},[11571,11575,11580,11584,11588,11592,11596,11600,11604,11608,11612,11616,11620,11624,11628,11632,11636,11640,11644,11648,11652,11656,11660,11664,11668,11673,11677,11681],{"type":413,"tag":501,"props":11572,"children":11573},{"style":519},[11574],{"type":418,"value":3293},{"type":413,"tag":501,"props":11576,"children":11577},{"style":557},[11578],{"type":418,"value":11579},"aadToken ",{"type":413,"tag":501,"props":11581,"children":11582},{"style":519},[11583],{"type":418,"value":736},{"type":413,"tag":501,"props":11585,"children":11586},{"style":519},[11587],{"type":418,"value":11426},{"type":413,"tag":501,"props":11589,"children":11590},{"style":7436},[11591],{"type":418,"value":11465},{"type":413,"tag":501,"props":11593,"children":11594},{"style":519},[11595],{"type":418,"value":8854},{"type":413,"tag":501,"props":11597,"children":11598},{"style":557},[11599],{"type":418,"value":11474},{"type":413,"tag":501,"props":11601,"children":11602},{"style":519},[11603],{"type":418,"value":8499},{"type":413,"tag":501,"props":11605,"children":11606},{"style":557},[11607],{"type":418,"value":11483},{"type":413,"tag":501,"props":11609,"children":11610},{"style":519},[11611],{"type":418,"value":704},{"type":413,"tag":501,"props":11613,"children":11614},{"style":519},[11615],{"type":418,"value":8303},{"type":413,"tag":501,"props":11617,"children":11618},{"style":557},[11619],{"type":418,"value":11496},{"type":413,"tag":501,"props":11621,"children":11622},{"style":519},[11623],{"type":418,"value":704},{"type":413,"tag":501,"props":11625,"children":11626},{"style":519},[11627],{"type":418,"value":8303},{"type":413,"tag":501,"props":11629,"children":11630},{"style":557},[11631],{"type":418,"value":11509},{"type":413,"tag":501,"props":11633,"children":11634},{"style":519},[11635],{"type":418,"value":11514},{"type":413,"tag":501,"props":11637,"children":11638},{"style":519},[11639],{"type":418,"value":11519},{"type":413,"tag":501,"props":11641,"children":11642},{"style":519},[11643],{"type":418,"value":11426},{"type":413,"tag":501,"props":11645,"children":11646},{"style":7436},[11647],{"type":418,"value":11528},{"type":413,"tag":501,"props":11649,"children":11650},{"style":519},[11651],{"type":418,"value":8854},{"type":413,"tag":501,"props":11653,"children":11654},{"style":557},[11655],{"type":418,"value":11537},{"type":413,"tag":501,"props":11657,"children":11658},{"style":519},[11659],{"type":418,"value":704},{"type":413,"tag":501,"props":11661,"children":11662},{"style":519},[11663],{"type":418,"value":11519},{"type":413,"tag":501,"props":11665,"children":11666},{"style":519},[11667],{"type":418,"value":784},{"type":413,"tag":501,"props":11669,"children":11670},{"style":583},[11671],{"type":418,"value":11672},"https://graph.windows.net",{"type":413,"tag":501,"props":11674,"children":11675},{"style":519},[11676],{"type":418,"value":580},{"type":413,"tag":501,"props":11678,"children":11679},{"style":519},[11680],{"type":418,"value":5503},{"type":413,"tag":501,"props":11682,"children":11683},{"style":557},[11684],{"type":418,"value":11567},{"type":413,"tag":501,"props":11686,"children":11687},{"class":503,"line":649},[11688,11692,11696,11701,11705,11709,11713,11718,11722,11726,11730,11735,11739,11744,11748,11752,11756],{"type":413,"tag":501,"props":11689,"children":11690},{"style":567},[11691],{"type":418,"value":8058},{"type":413,"tag":501,"props":11693,"children":11694},{"style":519},[11695],{"type":418,"value":2758},{"type":413,"tag":501,"props":11697,"children":11698},{"style":557},[11699],{"type":418,"value":11700},"AadAccessToken ",{"type":413,"tag":501,"props":11702,"children":11703},{"style":519},[11704],{"type":418,"value":3293},{"type":413,"tag":501,"props":11706,"children":11707},{"style":557},[11708],{"type":418,"value":11579},{"type":413,"tag":501,"props":11710,"children":11711},{"style":519},[11712],{"type":418,"value":2707},{"type":413,"tag":501,"props":11714,"children":11715},{"style":557},[11716],{"type":418,"value":11717},"MsAccessToken ",{"type":413,"tag":501,"props":11719,"children":11720},{"style":519},[11721],{"type":418,"value":3293},{"type":413,"tag":501,"props":11723,"children":11724},{"style":557},[11725],{"type":418,"value":11452},{"type":413,"tag":501,"props":11727,"children":11728},{"style":519},[11729],{"type":418,"value":2707},{"type":413,"tag":501,"props":11731,"children":11732},{"style":557},[11733],{"type":418,"value":11734},"AccountId ",{"type":413,"tag":501,"props":11736,"children":11737},{"style":519},[11738],{"type":418,"value":3293},{"type":413,"tag":501,"props":11740,"children":11741},{"style":557},[11742],{"type":418,"value":11743},"context.Account.Id ",{"type":413,"tag":501,"props":11745,"children":11746},{"style":519},[11747],{"type":418,"value":2707},{"type":413,"tag":501,"props":11749,"children":11750},{"style":557},[11751],{"type":418,"value":8067},{"type":413,"tag":501,"props":11753,"children":11754},{"style":519},[11755],{"type":418,"value":3293},{"type":413,"tag":501,"props":11757,"children":11758},{"style":557},[11759],{"type":418,"value":11760},"context.tenant.id\n",{"type":413,"tag":1556,"props":11762,"children":11764},{"id":11763},"summary",[11765],{"type":418,"value":11766},"Summary",{"type":413,"tag":414,"props":11768,"children":11769},{},[11770,11772,11777],{"type":418,"value":11771},"In this post, I wanted to show the different steps to configure Teams Tab SSO in PowerShell. The final script can be found ",{"type":413,"tag":432,"props":11773,"children":11775},{"href":7812,"rel":11774},[436],[11776],{"type":418,"value":3536},{"type":418,"value":11778}," and is directly used in an Azure pipeline to automate this configuration. Although it does the job, I hope doing such Azure AD configurations will be supported soon in Pulumi as it would have been easier to set it up instead of coming up with a big PowerShell script like this which is not idempotent.",{"type":413,"tag":3363,"props":11780,"children":11781},{},[11782],{"type":418,"value":3367},{"title":401,"searchDepth":540,"depth":540,"links":11784},[11785,11786,11795],{"id":7819,"depth":540,"text":7822},{"id":7851,"depth":540,"text":7854,"children":11787},[11788,11789,11790,11791,11792,11793,11794],{"id":7885,"depth":598,"text":7888},{"id":8084,"depth":598,"text":8087},{"id":8185,"depth":598,"text":8188},{"id":8259,"depth":598,"text":8262},{"id":8380,"depth":598,"text":8383},{"id":9232,"depth":598,"text":9235},{"id":9832,"depth":598,"text":9835},{"id":11156,"depth":540,"text":11159,"children":11796},[11797],{"id":11763,"depth":598,"text":11766},"content:1.posts:7.teams-sso-powershell.md","1.posts/7.teams-sso-powershell.md",1716749600665]