{"id":20626479,"url":"https://github.com/chgeuer/azure_automation_postgresql_msi","last_synced_at":"2026-05-06T13:14:25.973Z","repository":{"id":68104980,"uuid":"208064020","full_name":"chgeuer/azure_automation_postgresql_msi","owner":"chgeuer","description":"A demo bringing together Azure Automation, PostgreSQL and user-assigned managed identity","archived":false,"fork":false,"pushed_at":"2019-09-30T08:58:37.000Z","size":103,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-17T06:26:34.802Z","etag":null,"topics":["azure","azure-active-directory","azure-automation-runbooks","azure-resource-manager","postgresql"],"latest_commit_sha":null,"homepage":"","language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chgeuer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-12T13:58:27.000Z","updated_at":"2024-09-03T17:13:21.000Z","dependencies_parsed_at":"2023-09-12T10:15:20.547Z","dependency_job_id":null,"html_url":"https://github.com/chgeuer/azure_automation_postgresql_msi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgeuer%2Fazure_automation_postgresql_msi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgeuer%2Fazure_automation_postgresql_msi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgeuer%2Fazure_automation_postgresql_msi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgeuer%2Fazure_automation_postgresql_msi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chgeuer","download_url":"https://codeload.github.com/chgeuer/azure_automation_postgresql_msi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242483346,"owners_count":20135784,"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-active-directory","azure-automation-runbooks","azure-resource-manager","postgresql"],"created_at":"2024-11-16T13:13:33.114Z","updated_at":"2026-05-06T13:14:20.954Z","avatar_url":"https://github.com/chgeuer.png","language":"PowerShell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `azure_automation_postgresql_msi` - A demo bringing together Azure Automation, PostgreSQL and user-assigned managed identity.\n\n## Deploy\n\n- [deploy](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fchgeuer%2Fazure_automation_postgresql_msi%2Fmaster%2Ftemplates%2Fazuretemplate.json)\n\n```powershell\n$repo = \"chgeuer/external_azureautomation_runbooks\"\n$revision = \"d83c4994f2c93232720a987609fd7d2a712de05a\"\n(New-Object System.Net.WebClient).DownloadFile(\n    \"https://raw.githubusercontent.com/$repo/$revision/Utility/ARM/New-OnPremiseHybridWorker.ps1\",\n    \"C:\\Program Files\\WindowsPowerShell\\Scripts\\New-OnPremiseHybridWorker.ps1\");\n\n$s = \"JoinAzureAutomationHybridWorkerGroup.ps1\"\n(New-Object System.Net.WebClient).DownloadFile(\n    \"https://raw.githubusercontent.com/chgeuer/azure_automation_postgresql_msi/master/serverscripts/$s\",\n    \"$s\");\n.\\JoinAzureAutomationHybridWorkerGroup.ps1\n```\n\n## Requirements\n\n- A multi-tenant SaaS solution stores tenant-specific management information in PostgreSQL.\n  - Such management information could be a list of customer tenants, alongside with the Azure subscription IDs.\n- Azure Automation should be able to fetch management information from that PostgreSQL instance.\n- Azure Automation should be able to communicate with a PostgreSQL endpoint,\n  which is not public accessible on the Internet, but only visible within an Azure VNET.\n- Azure Automation should be able to manage resources in multiple Azure subscriptions.\n- All sensitive information (connection strings, etc.) should be stored in Azure KeyVault.\n- Favor 'user-assigned managed identity' over service principals.\n  - Whereever possible, try to avoid Azure service principals.\n  - 'Regular' service principals require that the applications securely handle the SP's secret/password/certificate.\n\n## Props\n\n- A user-assigned managed identity which is authorized for a few things:\n  - Fetch the PostgreSQL database connection string from KeyVault\n  - Has contributor rights on subscriptions, or individual resource groups\n- A hybrid worker VM,\n  - which has PostgreSQL ODBC driver installed,\n  - which has access to that user-assigned identity,\n  - is conneced to Azure Automation and can run the Powershell runbook runs, which\n    - uses the user-assigned identity to fetch PostgreSQL connection information from KeyVault\n    - establish a SQL connection to PostgreSQL,\n    - retrieve the list of tenants and subscriptions (using the ODBC driver using .NET from PowerShell)\n  - Connect to these subscriptions or resource groups, and do some Azure management operation,\n    such as listing all resource groups etc\n  - No local SP credentials stored on the VM\n- An Azure Automation account in which I can do the same as the hybrid worker VM (also connect to PostgreSQL),\n  just with the difference that it uses the Azure Automation account’s service principal account,\n  instead of a user-assigned identity.\n- An Azure Image Builder which creates VM images to be used for the hybrid worker VM\n\n- The idea for using a hybrid worker VM with Azure Automation was that, if the PostgreSQL DB is only\n  reachable inside a VNET, instead of exposing a public (Internet) endpoint. When using a private endpoint\n  for PostgreSQL, there’s a fair chance that Azure Automation-hosted runbooks would not be able to connect\n  to the private PostgreSQL instance. Having a VM image, we can simply spin a VM for Azure Automation\n  in a VNET of your choice…\n\n## Result\n\n- No service principals needed. Only user-assigned managed identity. No SP credentials on VMs.\n- Azure Automation scripts using data from PostgreSQL database. Azure Automation being able\n  to access PostgreSQL DB, even with Private Link.\n- Support for multiple subscriptions.\n\n\n## Demo walkthrough\n\n1. Choose password and prefix\n    password: G6zu8.-JkG5th\n    prefix: uniqprefixde123\n2. Deploy ARM template `templates/azuretemplate.json`\n3. put prefix value into `vars.json`\n4. Give the user-assigned identity contributor rights on one or more subscriptions or resource groups\n5. Run `clientscripts\\Get-SQL-Password.cmd` and paste the previously selected password\n6. Validate your setting by running `clientscripts\\sql_display_connection.cmd` or by running `type %USERPROFILE%\\.pgpass`\n7. Tweak `sql\\create_table_and_sampledata.sql` with your subscription IDs\n8. Install psql.exe from [PostgreSQL](https://www.enterprisedb.com/download-postgresql-binaries)\n9. Run `clientscripts\\sql_setup.cmd`\n\nYou should see\n\n```\nPS C:\\\u003e .\\clientscripts\\sql_setup.cmd\nCREATE DATABASE\nCREATE TABLE\nINSERT 0 2\n  tenant_name  |           subscription_id\n---------------+--------------------------------------\n Christian Sub | ....\n Holger Sub    | ...\n ```\n\n10. Navigate to the automation account / \"hybrid worker groups\" and check that there is a group with VMs in it\n11. You should be able to use the prefix as username, and the password to mstsc.exe into the VMs\n12. On the automation account, select the \"PostgreSQL-Managed-Identity-Crawler\" runbook, and run it on the Hybrid Worker pool.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchgeuer%2Fazure_automation_postgresql_msi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchgeuer%2Fazure_automation_postgresql_msi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchgeuer%2Fazure_automation_postgresql_msi/lists"}