{"id":50565722,"url":"https://github.com/webstean/webstean","last_synced_at":"2026-06-04T14:30:42.630Z","repository":{"id":157380776,"uuid":"370019582","full_name":"webstean/webstean","owner":"webstean","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-12T09:48:21.000Z","size":140,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-12T18:47:46.032Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webstean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-05-23T10:14:59.000Z","updated_at":"2026-01-12T09:48:25.000Z","dependencies_parsed_at":"2025-12-29T03:11:46.930Z","dependency_job_id":null,"html_url":"https://github.com/webstean/webstean","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/webstean/webstean","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstean%2Fwebstean","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstean%2Fwebstean/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstean%2Fwebstean/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstean%2Fwebstean/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webstean","download_url":"https://codeload.github.com/webstean/webstean/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webstean%2Fwebstean/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33910136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-06-04T14:30:42.570Z","updated_at":"2026-06-04T14:30:42.624Z","avatar_url":"https://github.com/webstean.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"### Hey there! I'm Andrew \u003cimg src=\"https://blog.joypixels.com/content/images/2019/06/waving_hand_sign_1024.gif\" width=\"40px\"\u003e\n\u003cbr\u003e\n\u003ca href=\"https://twitter.com/webstean\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Twitter-@webstean-1DA1F2?style=flat\u0026logo=twitter\u0026logoColor=white\" alt=\"Twitter Badge\"/\u003e\n\u003c/a\u003e\n\u003ca href=\"https://www.linkedin.com/in/maketechwork/\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/LinkedIn-MakeTechWork-0077B5?style=flat\u0026logo=linkedin\u0026logoColor=white\" alt=\"LinkedIn Badge\"/\u003e\n\u003c/a\u003e\n\u003ca href=\"mailto:webstean@gmail.com\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Email-webstean@gmail.com-D14836?style=flat\u0026logo=gmail\u0026logoColor=white\" alt=\"Email Badge\"/\u003e\n\u003c/a\u003e\n\u003cbr\u003e\n\n## 📄 About Me\n\u003cbr\u003e\n⚡ I am a IT architect, engineer, mentor, and cloud advocate with over 20 years professional experience. I specialise in designing the hosting of enterprise applications and solutions, principally in the Azure Cloud. I love a challenge and I'm skilled at progressing from a simple proposal into a well-defined, robust and production ready solution. My experence goes beyond the typical compute, network and storage, as I have been involved in several large consolidation and migration projects of Oracle and Microsoft SQL Server databases, sometimes involving virtualisation other times in (or out) of public clouds like AWS or Azure.\u003cbr\u003e \n\n🌱 I enjoy with working with developers and security/cyber indivduals, to help optimise their way of working and deliver better overall outcomes ensuring both security, reliability and agility to evolve as things change.\u003cbr\u003e\n\n👯 I live and work in [Melbourne, Australia](https://en.wikipedia.org/wiki/Melbourne). But over my career I have lived and worked in [Singapore](https://en.wikipedia.org/wiki/Singapore), [Tokyo, Japan](https://en.wikipedia.org/wiki/Tokyo) and [North Carolina, USA](https://en.wikipedia.org/wiki/North_Carolina).\u003cbr\u003e\n\n[Terraform](https://developer.hashicorp.com/terraform/docs) has been my new favourite bit of tech in the last few years - it solves so many of the \"infra\" challenges in a simple, elegant and intuitive way.\u003cbr\u003e I just love how I can deploy totally repeatable infrastructure accorss multiple cloud regions. I've even used to managed VMware ESXi clusters.\n\nCurrently, I am enjoying the full Terraform support in [AZD](https://github.com/Azure/azure-dev) and [ADE](https://learn.microsoft.com/en-us/azure/deployment-environments/how-to-configure-extensibility-model-custom-image), that can be used together to combined infrastructure provisioning and application deployment in the same step. This is particularly useful during GitHub Actions / ADO Pipelines -as an example:- \u003cbr\u003e\n```shell\n## Provision Infrastructure\nazd provision\n## Deploy Application\nazd deploy\n### or do both, with one step\nazd up\n```\nSee [here](https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/) and [here](https://learn.microsoft.com/en-us/azure/deployment-environments/) for the complete documentation\n\n\u003c!---\n## 📄 Some GitHub States\n\u003cbr\u003e\n\u003ca href=\"https://github.com/webstean\"\u003e\n  \u003cimg height=\"180em\" src=\"https://github-readme-stats.vercel.app/api?username=webstean\u0026show_icons=true\u0026theme=shades-of-purple\u0026count_private=true\" alt=\"webstean's GitHub Stats\" /\u003e\n  \u003cimg height=\"180em\" src=\"https://github-readme-stats.vercel.app/api/top-langs/?username=webstean\u0026theme=shades-of-purple\u0026layout=compact\" \n    alt=\"Andrew Webster GitHub Top Languages\" /\u003e\n\u003c/a\u003e\n--\u003e\n\n\u003c!--\n**webstean/webstean** is a ✨ _special_ ✨ repository because its `README.md` (this file) appears on your GitHub profile.\n\nHere are some ideas to get you started:\n\n- 🔭 I’m currently working on ...\n- 🌱 I’m currently learning ...\n- 👯 I’m looking to collaborate on ...\n- 🤔 I’m looking for help with ...\n- 💬 Ask me about ...\n- 📫 How to reach me: ...\n- 😄 Pronouns: ...\n- ⚡ Fun fact: ...\n--\u003e\n\u003cbr\u003e\n\u003cbr\u003e\n\n## 📄 Some Useful Links\n\n#### API Examples etc..\nExample Public APIs      : https://github.com/public-apis/public-apis\u003cbr\u003e\nAPIM CheatSheet          : https://github.com/Azure/api-management-policy-snippets/blob/master/policy-expressions%2FREADME.md/\u003cbr\u003e\n\n#### Azure Portal Links\nDeveloper Portal         : https://devportal.microsoft.com\u003cbr\u003e\nDeveloper Portal2(!)     : https://dev.teams.microsoft.com/home\u003cbr\u003e \nDevBox Portal            : https://devbox.microsoft.com/\u003cbr\u003e \nAzure Portal             : https://portal.azure.com\u003cbr\u003e\n*Preview* Azure Portal   : https://preview.portal.azure.com/\u003cbr\u003e\n*RC* Azure Portal        : https://rc.portal.azure.com/\u003cbr\u003e\n\n#### Microsoft / Azure Icons\nAzure                    : https://learn.microsoft.com/en-us/azure/architecture/icons/\u003cbr\u003e\nPower Platform           : https://learn.microsoft.com/en-us/power-platform/guidance/icons\u003cbr\u003e\nDynamics 365             : https://learn.microsoft.com/en-us/dynamics365/get-started/icons\u003cbr\u003e\nMicrosoft 365            : https://learn.microsoft.com/en-us/microsoft-365/solutions/architecture-icons-templates?view=o365-worldwide\u003cbr\u003e\n\n#### Microsoft / Azure Documentation\nTracker                  : https://msdocstracker.com/\u003cbr\u003e\nMain Page                : https://learn.microsoft.com\u003cbr\u003e\n\n#### Terraform \nTerraform Awesome        : https://github.com/shuaibiyy/awesome-tf/blob/master/README.md\u003cbr\u003e\nProvider: Azurerm        : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs\u003cbr\u003e\nProvider: Entra          : https://registry.terraform.io/providers/hashicorp/azuread/latest/docs  (future (now in beta): https://registry.terraform.io/providers/microsoft/msgraph/latest \u003cbr\u003e\nProvider: azapi          : https://registry.terraform.io/providers/hashicorp/azuread/latest/docs\u003cbr\u003e\nProvider: Power Platform : https://registry.terraform.io/providers/microsoft/power-platform/latest/docs\u003cbr\u003e\nProvider: Fabric         : https://registry.terraform.io/providers/microsoft/fabric/latest\u003cbr\u003e\nAzure Verified Modules   : https://azure.github.io/Azure-Verified-Modules/\u003cbr\u003e\n\n## 📄 **My Top Tip** - Use OIDC Federation (Open ID Connect)\nWhen using Terraform providers as part of GitHub / Dev Ops actions / pipelines, please use OIDC Federation (OpenID Connect) for better security, that way you require no secrets or certificatres to expired or get compromised.\u003cbr\u003e\nThis works and fully support with both GiutHub Actions and Azure DevOps (ADO) pipelines. The relevant documentation links can be found below:\u003cbr\u003e\n[Setting up Terraform Azure provider to use OIDC Federation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_oidc)\u003cbr\u003e\n[Setting up Terraform Entra ID provider to use OIDC Federation](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/guides/service_principal_oidc)\u003cbr\u003e\n[Setting up Terraform Power Platform provider to use OIDC Federation](https://registry.terraform.io/providers/microsoft/power-platform/latest/docs#authenticating-to-power-platform-using-a-service-principal-with-oidc)\u003cbr\u003e\n\n```hcl\n## Example: Add a Federation identity for GitHub to an Azure Application\n## Generally, I'd recommend using the alterantive (User Assigned Identity) as per below\n## as its a smaller footprint\nresource \"azuread_application_federated_identity_credential\" \"example_federation\" {\n  for_each = github_repository.example\n\n  display_name   = \"fedcred-example-github\"\n  application_id = azuread_application.yourapp.id\n  audiences      = [\"api://AzureADTokenExchange\"]\n  issuer         = \"https://token.actions.githubusercontent.com\"\n  description    = \"Federated identity for ....\"\n  ## permission for just the main branch\n  subject        = \"repo:${each.value.full_name}:ref:refs/heads/main\"\n  ## permission for the GitHub environmnet\n  subject        = \"repo:${each.value.full_name}:environment:${var.environment_name}\" ## this is for the environment, but you use branch (such as main)\n}\n\n## Example: Add a Federation identity for GitHub to an Azure User Managed Identity (UMI)\n## This works, even if you don't have the ability to created applications within Entra ID \nresource \"azurerm_federated_identity_credential\" \"example_federation\" {\n  for_each = github_repository.example\n\n  name                = \"fedcred-example-github\"\n  resource_group_name = azurerm_resource_group.example.name\n  audience            = [\"api://AzureADTokenExchange\"]\n  parent_id           = azurerm_user_assigned_identity.example.id\n  issuer              = \"https://token.actions.githubusercontent.com\"\n  ## permission for just the main branch\n  subject             = \"repo:${each.value.full_name}:ref:refs/heads/main\"\n  ## permission for the GitHub environmnet\n  subject             = \"repo:${each.value.full_name}:environment:${var.environment_name}\" ## this is for the environment, but you use branch (such as main)\n}\n```\nIf you've read this far, you might be asking Q: Isn't a User Assigned Identities a bit limiting? You cannot give them access to read Microsoft Graph and therefore they cannot read users, groups or applications, like when trying to authenticate users via easy auth or for SQL Server etc...\u003cbr\u003e\n\u003e [!IMPORTANT]\n\u003e Whilst it is *NOT possible* to add Microsoft Graph permissions to an Entra ID Service Principal (such as a Managed Identity) in the Azure portal, it can done it via the API.\n\u003e And, in terraform, you achieve this will the folowing:\u003cbr\u003e\n## System Assigned Identies - MS Graph permissions\n```hcl\ndata \"azuread_application_published_app_ids\" \"well_known\" {}\n\nresource \"azuread_service_principal\" \"msgraph\" {\n  client_id    = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph\n  use_existing = true\n}\n\nresource \"azuread_app_role_assignment\" \"sqlserver_system_identity_graph_user_read_all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"User.Read.All\"]\n  principal_object_id = data.azurerm_mssql_server.identity[0].principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\nresource \"azuread_app_role_assignment\" \"sqlserver_system_identity_graph_group_read_all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"Group.Read.All\"]\n  principal_object_id = data.azurerm_mssql_server.identity[0].principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\nresource \"azuread_app_role_assignment\" \"sqlserver_system_identity_graph_groupmember_read_all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"GroupMember.Read.All\"]\n  principal_object_id = data.azurerm_mssql_server.identity[0].principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\nresource \"azuread_app_role_assignment\" \"sqlserver_system_identity_graph_application_read_all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"Application.Read.All\"]\n  principal_object_id = each.value.identity[0].principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\n```\nFor example, you can assigned this system assigned identity of an Azure SQL Server, and then the server can use managed identity to managed access to the database, since the user assigned identity give it enough access to read Entra ID users, group (including group members) and applications. Read more about this [here](https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-azure-ad-user-assigned-managed-identity?view=azuresql)\n\nbut, even better you can use:\u003cbr\u003e\n## User Assigned Identies - MS Graph permissions\nThis gives you the ultimate in flexibility as you can apply these permission accross multiple resources, which ultimately requires less code to build and maintain.\u003cbr\u003e\n```hcl\ndata \"azuread_application_published_app_ids\" \"well_known\" {}\n\nresource \"azuread_service_principal\" \"msgraph\" {\n  client_id    = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph\n  use_existing = true\n}\n\nresource \"azurerm_user_assigned_identity\" \"example-identity\" {\n  name = \"id-example-with-graph-permissions\"\n\n  resource_group_name = azurerm_resource_group.example.name\n  location            = azurerm_resource_group.example.location\n  tags                = azurerm_resource_group.example.tags\n}\nresource \"azuread_app_role_assignment\" \"github-environment-identity-user-read-all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"User.Read.All\"]\n  principal_object_id = azurerm_user_assigned_identity.example.principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\nresource \"azuread_app_role_assignment\" \"github-environment-identity-group-read-all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"Group.Read.All\"]\n  principal_object_id = azurerm_user_assigned_identity.example.principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\nresource \"azuread_app_role_assignment\" \"github-environment-identity-group-member-read-all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"GroupMember.Read.All\"]\n  principal_object_id = azurerm_user_assigned_identity.example.principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\nresource \"azuread_app_role_assignment\" \"github-environment-identity-group-app-read-all\" {\n  app_role_id         = azuread_service_principal.msgraph.app_role_ids[\"Application.Read.All\"]\n  principal_object_id = azurerm_user_assigned_identity.example.principal_id\n  resource_object_id  = azuread_service_principal.msgraph.object_id\n}\n```\n\n## 📄 Code Snippet\n\nView the full code on Gist:\n\n[![View Gist](https://img.shields.io/badge/View%20Gist-f7792c2f97-blue?logo=github\u0026style=for-the-badge)](https://gist.github.com/webstean/f7792c2f971423591f3efe6bfd450c9a)\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebstean%2Fwebstean","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebstean%2Fwebstean","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebstean%2Fwebstean/lists"}