{"id":25072693,"url":"https://github.com/passadis/cosmosdb-adusers","last_synced_at":"2026-05-04T10:35:33.673Z","repository":{"id":181186297,"uuid":"461999780","full_name":"passadis/CosmosDB-ADUsers","owner":"passadis","description":"Entra ID User Registration with Cosmos DB","archived":false,"fork":false,"pushed_at":"2024-01-27T01:00:19.000Z","size":91,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T17:56:48.468Z","etag":null,"topics":["azure","azure-devops","azure-functions","ci-cd","cosmosdb","devops","dotnet","msgraph-api","nodejs","sdk"],"latest_commit_sha":null,"homepage":"https://www.cloudblogger.eu/2023/03/06/import-ad-users-from-html-form-using-cosmosdb-and-azure-functions/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/passadis.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"DOCS/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"DOCS/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"DOCS/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-21T19:17:43.000Z","updated_at":"2024-06-07T14:58:22.000Z","dependencies_parsed_at":"2024-01-10T03:41:41.785Z","dependency_job_id":"d011f4f7-13d7-470b-adb2-6e68961ea27d","html_url":"https://github.com/passadis/CosmosDB-ADUsers","commit_stats":null,"previous_names":["passadis/cosmosdb-adusers"],"tags_count":0,"template":false,"template_full_name":"staticwebdev/vanilla-basic","purl":"pkg:github/passadis/CosmosDB-ADUsers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passadis%2FCosmosDB-ADUsers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passadis%2FCosmosDB-ADUsers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passadis%2FCosmosDB-ADUsers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passadis%2FCosmosDB-ADUsers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/passadis","download_url":"https://codeload.github.com/passadis/CosmosDB-ADUsers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/passadis%2FCosmosDB-ADUsers/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262151864,"owners_count":23266930,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-devops","azure-functions","ci-cd","cosmosdb","devops","dotnet","msgraph-api","nodejs","sdk"],"created_at":"2025-02-06T22:33:13.229Z","updated_at":"2026-05-04T10:35:28.653Z","avatar_url":"https://github.com/passadis.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://skillicons.dev\"\u003e\n    \u003cimg src=\"https://skillicons.dev/icons?i=azure,powershell,html,css,dotnet,nodejs,vscode\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eRegister and Import Entra ID Users from Cosmos DB and Azure Functions with DevOps\u003c/h1\u003e\n \n\nThis Repo contains all the Pipelines needed to deploy a Solution that imports AD Users from an HTML Registration form. The form is hosted on Azure Static Apps, for later updates and enhancements.The procedure inserts the fields into Comsos DB via Azure Functions HTTP Trigger, checks for Unique ID on the nickname value, and if it is OK the data is stored. Another Function is triggered and the User details are transfromed to CSV and Stored in a Storage Blob. From there we can have an hourly or a Scheduled Trigger to start a Build Pipeline which copies the CSV into a Self Hosted DevOps Agent and uses MS Graph SDK (Powershell) to import the users to AzureAD. I have added a third Function that triggers the build Pipeline once the CSV is created ! So it is a fully automated procedure! \n\nA really nice Solution which integrates Azure Services \u0026 DevOps while most of the Deployment is automated.\nWe can add a Gate on the Build Pipeline so the procedure receives an approval, while the approver gets an Email.\n\n## We are going to need:\n\n- An Azure Subscription\n- VS Code\n- A DevOps Organization and a Self Hosted Agent with Standard Public IP\n- A Microsoft 365 Tenant with some trial licenses ( This is optional as the MS Graph also assigns the users into a Group with Licenses)\n- Patience!\n\nWhat we are doing here is:  \n- Deploy the Log Analytics Workspace\n- Deploy the Cosmos DB and the VNET\n- Deploy a Cosmos DB Container with Unique Key\n- Deploy the Function App with an Application Basic Plan (B1)\n- Configure CORS\n- Integrate the Function APP with the VNET\nThen Stage 2 is triggering a Build which Copies and runs a Powershell Script on the Self Hosted Agent that creates and configures the Private DNS Zone for Cosmos.\nOnce the Resources are up and running use the files on the repo folders.\n\n## Steps:\n\nThis is not a small deployment . A lot of parts are integrated so it does matter how to deploy and the steps to make it work. Lets start from the resources we deploy into an Azure Subscription.\n\nThe following release pipeline has 2 Stages. First Stage deploys:\n\n    Task 1 – Our resource group with a Log Analytics Workspace for the Application Insights (AzCli)\n    Task 2 – A Virtual Network , the Cosmos DB Account with VNET Integration and Private Endpoint(Arm)\n    Task 3 – Cosmos DB Container with Unique ID setting to prevent Duplicate Nickname/Email/UPN(Arm)\n    Task 4 – Function App(Arm)\n    Task 5 – Function App Subnet and CORS Setting(AzCli)\n    Task 6 – Function App VNET Injection(Powershell)\n\nThe Second Stage takes us to just a trigger to Start a Build Pipeline that deploys the Private Endpoint and the configuration to integrate it with the Private DNS Zone for CosmosDB. The way i chose to do this step can be done only via Build Pipeline!\n\nNow some details to clarify things. We are using Private Endpoints and Private DNS Zone therefore the VNET Injection setting from Azure Functions is mandatory. We are setting Unique ID for Cosmos DB field (nickname) so even the FirstName , LastName are the same a third field named Nickname will be checked upon and fail the HTML Signup with a message. The Nickname is handy to create a random password or the email and so on. We could use Synapse ( or Data Factory) to export the CSV, but the standard way of Azure Functions with a second Function triggering upon Cosmos DB change, was the final choice. It took me a long time to make the code work i have to admit!\n\nThe end user is hitting a URL ( Of course custom domain can be configured, either in Static Apps or Storage Account Static WebSite), and is presented with the HTML Form where inputs First Name , Last Name and Nickname. If there is no duplicate a message is returned “Sign Up Completed” , otherwise (and on any failure) ‘Sign Up Failed”. It is important to set the CORS setting in Azure Functions to * in order to accept data from any URL.\n\n## Contribution\n\nContributions are welcome! If you have suggestions or improvements, feel free to fork the repository, make your changes, and submit a pull request.\n\nThe Folders contain the Release and Build Pipelines needed to deploy the basis of the Solution. Once we run the release Pipeline Stage 2 triggers the Build Pipeline which deploys the Private DNS Zone and adds the Cosmos DB Configuration of the Private Endpoint.\n\nContact me if you have an idea to make this better!\n\n## Instructions\n**Follow the Blog for Detailed Instructions**: For step-by-step guidance, visit [Import AD Users from HTML Form using CosmosDB and Azure Functions](https://www.cloudblogger.eu/2023/03/06/import-ad-users-from-html-form-using-cosmosdb-and-azure-functions/).\n\n## Architecture\n\n![image](https://user-images.githubusercontent.com/53148138/223159115-e4dda8f8-930e-4d7c-b6d0-8d4cb60006d9.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpassadis%2Fcosmosdb-adusers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpassadis%2Fcosmosdb-adusers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpassadis%2Fcosmosdb-adusers/lists"}