[{"body":"","link":"https://benoit-gaumard.io/blog/","section":"","tags":null,"title":""},{"body":"","link":"https://benoit-gaumard.io/blog/tags/bastion/","section":"tags","tags":null,"title":"Bastion"},{"body":"","link":"https://benoit-gaumard.io/blog/categories/bastion/","section":"categories","tags":null,"title":"Bastion"},{"body":"","link":"https://benoit-gaumard.io/blog/categories/","section":"categories","tags":null,"title":"Categories"},{"body":"Connect directly to your Azure virtual machines using the native RDP client through Bastion.\nIntroduction Azure Bastion is a fully managed PaaS service that provides secure and seamless RDP/SSH connectivity to your virtual machines directly over TLS from the Azure portal, or via the native SSH or RDP client already installed on your local computer.\nOfficial documentation is available here: https://learn.microsoft.com/en-us/azure/bastion/bastion-overview\nNative client support is a feature in Azure Bastion, which allows users to use native SSH and RDP programs to connect to Bastion instead of using the Azure Bastion web interface.\nPrequisites Azure Bastion deployed Note Native client support must be enabled on Bastion to create the tunnel.\nAzure Bastion Native Client Support Instead of logging in through the Azure Portal, Azure Bastion now allows users to connect using their native RDP or SSH clients.\nGo to Bastion --\u0026gt; Settings --\u0026gt; Configuration --\u0026gt; Native client support.\nCreate the RDP tunnel Open a terminal:\n1az login --tenant \u0026lt;your_tenant_id\u0026gt; --use-device-code 2az account set --subscription \u0026lt;your_subscription_id\u0026gt; Define your variables to target the VM to connect to:\n1$BastionName = \u0026#34;bstbga01\u0026#34; 2$BastionRG = \u0026#34;rg-bst\u0026#34; 3$TargetVmResourceId = \u0026#34;/subscriptions/xxx-xxx-xxx-xxx/resourceGroups/rg-vm/providers/Microsoft.Compute/virtualMachines/vmapp001\u0026#34; Note To get the VM resoure Id go to:\nVirtual machines --\u0026gt; Select Your VM --\u0026gt; Overview --\u0026gt; JSON View --\u0026gt; Copy the Resource ID.\nCreate the tunnel:\n1az network bastion tunnel --name $BastionName ` 2 --resource-group $BastionRG ` 3 --target-resource-id $TargetVmResourceId ` 4 --resource-port \u0026#34;3389\u0026#34; ` 5 --port \u0026#34;50022\u0026#34; ` 6 --subscription xxx-xxx-xxx-xxx Open RDP connection to the VM:\n1mstsc /v:127.0.0.1:50022 You should now be connected to the target VM through the Azure Bastion tunnel. You can use this connection to manage the VM as needed.\nDon't forget to close the tunnel when done with Ctrl + C in the terminal where you started the tunnel.\nEnjoy!\n","link":"https://benoit-gaumard.io/blog/post/31-azure-bastion-tunnel-rdp/","section":"post","tags":["bastion"],"title":"Connect Azure VM using the native RDP client through Bastion"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/index/","section":"tags","tags":null,"title":"Index"},{"body":"","link":"https://benoit-gaumard.io/blog/post/","section":"post","tags":["index"],"title":"Posts"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/","section":"tags","tags":null,"title":"Tags"},{"body":"","link":"https://benoit-gaumard.io/blog/categories/azure/","section":"categories","tags":null,"title":"Azure"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/dns/","section":"tags","tags":null,"title":"DNS"},{"body":"How to delegate a domain to Azure DNS.\n1. Intro Azure DNS allows you to host a DNS domain and manage the DNS zone records. To host your domain in Azure, the zone must be created in Azure and delegated to Azure's authoritative DNS servers with a domain registrar.\nNote Azure DNS isn't a domain registrar, you must buy your domain name first from a registrar like GoDaddy, OHV, CloudFlare, etc.\nThe official documentation is available here:\nWhat is DNS delegation: https://learn.microsoft.com/en-us/azure/dns/dns-domain-delegation\nHost your domain in Azure DNS: https://learn.microsoft.com/en-us/azure/dns/dns-delegate-domain-azure-dns\n1. Context I own a domain name, quickquotemaker.io, which is used to display a website www.quickquotemaker.io that you can visit 🙂\nThe DNS zone management for this domain is handled by the registrar OVH when I purchased the domain name.\nFrom the OVH interface, I can manage my DNS zone and add any type of record as needed (A, CNAME, NS, MX, TXT, etc.).\nFor various applications hosted in Azure, I regularly need to create new DNS entries so that my applications can be accessed using domain names such as:\nhttp://myapp1.quickquotemaker.io http://myapp2.quickquotemaker.io www.quickquotemaker.io etc. To do this, I currently have to configure DNS settings in two different places (portals):\nThe Azure portal: https://portal.azure.com The OVH portal: https://www.ovh.com/manager The goal of this article is to show how to centralize DNS zone management in Azure by delegating the zone currently hosted by OVH.\n2. Creating a new Public DNS zone in Azure Azure DNS allows you to host a DNS zone and manage DNS records for a domain directly in Azure. For DNS queries for a domain to reach Azure DNS, the domain must be delegated to Azure DNS from the parent domain.\nKeep in mind, Azure DNS is not the domain registrar, OVH remains the registrar\nSteps:\nSign in to the Azure portal and search for DNS Zone in the Marketplace. Click Create. Select an existing resource group or create (eg.quickquotemaker.io) a new one.\nIn the Name field, enter the DNS zone name to create.\nChoose the resource group location (eg. West Europe).\nAdd tags if necessary.\nClick Create.\nNote Azure allows you to create a DNS zone with any name (e.g., microsoft.com, google.fr, toto.local), even if you are not the owner. However, to actually manage the zone and add records, you must be the domain owner.\nTo manage the zone, Azure provides four Name Servers (NS) by default to ensure redundancy in case of failure.\nNote Copy the NS server names and keep them handy, they will be required to configure the delegation in the OVH portal.\n3. Delegate the domain Now that the DNS zone is created and we have the name servers, we need to update the parent domain with the Azure DNS name servers. Each registrar has its own tools (portal, etc.) for managing DNS and modifying name server records.\nSteps in OVH:\nGo back to the OVH portal.\nNavigate to the DNS Servers menu.\nClick Modify DNS Servers.\nSelect Use my own DNS.\nAdd the four Azure DNS name servers (remove the trailing dot).\nDelete the existing OVH NS entries. Click Apply Configuration.\nDNS Servers for the zone are now the Azure DNS Servers. Note Be careful, your websites and services associated with the domain (mail, FTP, etc.) will be temporarily unavailable during this operation.\n4. Create DNS records Note Now that Azure DNS is responsible for managing the zone. All administratistes tasks should be done on Azure. Do nothing on OVH portal.\nFirst, You need to recreate the appropriate DNS records (A, CNAME, NS, MX, TXT, etc.) so that services return to normal, to display your website correctly.\nTo display my website, the first record to create in Azure DNS is an A record pointing to the public IP address of my website provided by OVH.\nIn Azure DNS, click Add Record set\nLeave the Name field empty or enter @ (this corresponds to the root of the domain).\nSelect record type A.\nLeave the default TTL.\nAdd the public IP address of the website.\nOnce the record is created, you should see the corresponding entry. Next, create a www record of type CNAME pointing to the root domain. 5. Test the delegation Once the delegation is complete, you can verify that it works using a tool such as nslookup or https://www.zonemaster.net/ to query the zone. You may need to wait 10 minutes or more after delegation before verification. DNS propagation can take some time.\nThere is no need to explicitly specify the Azure DNS name servers. If the delegation is configured correctly, the standard DNS resolution process will automatically detect the Azure name servers.\nFrom a command prompt, run the following commands:\nClear the cache first 1ipconfig /flushdns Then check the SOA with this command 1nslookup -type=SOA quickquotemaker.io Verify that the response looks like the expected nslookup output.\nTo display the name servers, run: 1nslookup -type=NS quickquotemaker.io Verify that the response matches the Azure DNS name servers.\nAnother test can be performed using the www record.\nThe site is now accessible via both URLs, and DNS record management is performed directly from the Azure portal.\nNote All DNS management actions like add / delete / modify records should be done onbly from Azure only. Add a Delete lock on your DNS resource group to prevent accidental deletion.\nEnjoy! 🚀\n","link":"https://benoit-gaumard.io/blog/post/15-how-to-delegate-a-domain-to-azure-dns/","section":"post","tags":["DNS"],"title":"How to delegate a domain to Azure DNS"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nContribution scenarios You can contribute to a GitHub project in several ways:\nReporting bugs Submitting fixes Proposing new features Becoming a maintainer ... Main principles The main branch is protected, preventing direct commits. Developers work in their own branches derived from the main branch. Developers submit pull requests for their changes. Once a pull request is approved, the code is merged. A release is then created. The new code is deployed via a deployment pipeline. Here is the main contribution workflow:\nSteps for contribution 0. Prerequisites Ensure Git is installed on your machine: Git Downloads Have a code editor (IDE) ready, such as Visual Studio Code 1. Pull the latest changes from upstream into your local repository To start working on your contribution, you need first to retrieve the project on your local repository.\nTo do so, use this command :\n1git clone https://github.com/Benoit-Gaumard/ProjectName Note Replace \u0026quot;ProjectName\u0026quot; by the actual project you want to contribute to.\nBefore you start making any changes to your local files, it's a good practice to first synchronize your local repository with the project repository.\nUse the following command to \u0026quot;pull\u0026quot; any changes from the \u0026quot;master\u0026quot; branch of the \u0026quot;upstream\u0026quot; into your local repository.\n1# If the default branch is \u0026#34;main\u0026#34; 2git pull upstream main Note If the project repository uses \u0026quot;main\u0026quot; instead of \u0026quot;master\u0026quot; for its default branch, then you would use git pull upstream main instead.\n2. Create a new branch See the Branch Naming convention page here::\nRather than making changes to the project's \u0026quot;master\u0026quot; branch, it's a good practice to instead create your own branch. This creates an environment for your work that is isolated from the master branch.\nUse this command to create a new branch and then immediately switch to it. The name of the branch should briefly describe what you are working on, and should not contain any spaces.\n1git checkout -b my_new_feature For example, I used git checkout -b doc-fixes because I was making some small fixes to the documentation.\nTo show your local branches, use this command :\n1git branch You should see your new branch as well as \u0026quot;master\u0026quot;, and your new branch should have an asterisk next to it to indicate that it's \u0026quot;checked out\u0026quot; (meaning that you're working in it).\n3. Make changes in your local repository​ Open a text editor or IDE such as Visual Studio Code to implement the changes you have planned in your local repository. Since you checked out a branch in the previous step, any modifications you make will be confined to that branch.\nYou can download Visual Studio Code here: Visual Studio Code\n4. Commit your changes​ See the Commit convention page here::\nAfter you make a set of changes, use the following command to stage your changes.\n1git branch Add all changes\n1git add . The description of your commit must be clear, explicit and understandable to anyone, example :\n1git commit -m \u0026#34;fix: typos in set_config docstring\u0026#34; Note This commit message might be included in a changelog.\nCommit messages must be standardized: Conventional Commits\n- feat: my new feature description - release: my new realease description - hotfix: my hotfix description - fix: my fix description If you are making multiple sets of changes, it's a good practice to make a commit after each set.\n5. Push changes to your branch​ When you are done making all of your changes, upload these changes to your branch using :\n1git push origin my_new_feature This command \u0026quot;pushes\u0026quot; your changes to the \u0026quot;my_new_feature\u0026quot; branch of the \u0026quot;origin\u0026quot; (which is your fork on GitHub).\n6. Create a pull request​ A GIT pull request occurs when a developer asks for changes committed to a specific branch to be considered for inclusion in an other branch of the repository.\nGo to your Github project web page in the Pull request menu and click on New pull request.\nOnce it's done, click on Create pull request.\nIf there is no conflicts between your fork and the main branch, your pull request will be created and contributors will be notify. The contributors will then analyze your fork and choose to merge your code or not.\nYou should then add some colleagues working on the repository as reviewers and yourself as an assignee, reviewers will be notified by email automatically.\nAs a best practice, you should let your collegues know your pull request creation (through a Microsoft Teams message, or vocally), as emails from github are very frequently ignored.\n7. Code Review​ Before merging, the code should be reviewed by peers, code review involves one or more team members checking another teammate's work.\n8. Merge to the main branch​ Congratulations! Your code has been successfully reviewed and merged into the main branch. It is now available for others to build upon for future contributions.\n9. Golden rules ✅ Commit each day\n✅ Never commit directly to the main branch and always protect it\n✅ Adopt a naming convention for your branches (eg. feat: for a new feature, fix: for a bug fix)\n✅ Adopt a naming convention for your commits (eg. feat: for a new feature, fix: for a bug fix)\n✅ Enhance security in your code with the principle of least privilege\n✅ All should be deleted an recreated otherwise it's not IAC\n","link":"https://benoit-gaumard.io/blog/post/25-github-contribution-workflow/","section":"post","tags":["GitHub","Productivity"],"title":"✨ GitHub contribution workflow"},{"body":"A stylish way to showcase the latest commits from a repository.\nDisplay latest commits with git graph 1git log --graph --oneline --all --decorate --topo-order --pretty=format:\u0026#39;%C(cyan)%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(magenta)\u0026lt;%an\u0026gt;%Creset\u0026#39; --abbrev-commit --date=relative -n 20 ","link":"https://benoit-gaumard.io/blog/post/28-display-latest-commits-with-git-graph/","section":"post","tags":["Git","Productivity"],"title":"Display latest commits with Git Graph"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/git/","section":"tags","tags":null,"title":"Git"},{"body":"","link":"https://benoit-gaumard.io/blog/categories/git/","section":"categories","tags":null,"title":"Git"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/github/","section":"tags","tags":null,"title":"GitHub"},{"body":"","link":"https://benoit-gaumard.io/blog/categories/github/","section":"categories","tags":null,"title":"GitHub"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/productivity/","section":"tags","tags":null,"title":"Productivity"},{"body":"You can connect to your Azure SQL Database or Azure Database for MySQL using a Managed Identity in PHP. This approach removes the necessity of storing usernames and passwords in your code. Authentication is managed by Entra ID, previously known as Azure Active Directory (AAD).\nhttps://techcommunity.microsoft.com/blog/appsonazureblog/how-to-access-azure-sql-database-with-managed-identity-in-php-in-app-service/4129014\nEnable Managed Identity for Your App Service If using Azure App Service (Web App): Go to Azure Portal → Your App Service → Identity → Enable System-assigned identity.\nAssign Database Permissions After enabling Managed Identity, you need to grant it access to your Azure database.\nFor Azure SQL Database, connect to your SQL Server using Azure Data Studio or SQL Server Management Studio (SSMS).\nRun the following SQL commands to create an AAD user and assign roles:\n1-- Create the Managed Identity as an Azure AD user 2CREATE USER [your-managed-identity-name] FROM EXTERNAL PROVIDER; 3 4-- Grant permissions (adjust based on needs) 5ALTER ROLE db_datareader ADD MEMBER [your-managed-identity-name]; 6ALTER ROLE db_datawriter ADD MEMBER [your-managed-identity-name]; 7ALTER ROLE db_owner ADD MEMBER [your-managed-identity-name]; -- Only if full access is needed To dispaly external providers created:\n1--SID to OBJECTID 2SELECT 3\tDP.name 4\t,DP.principal_id 5\t,DP.type 6\t,DP.type_desc 7\t,DP.SID 8\t,OBJECTID = CONVERT(uniqueidentifier, DP.SID) 9FROM SYS.database_principals DP 10WHERE DP.type IN (\u0026#39;S\u0026#39;,\u0026#39;X\u0026#39;,\u0026#39;E\u0026#39;) Replace your-managed-identity-name with the actual name of your managed identity. Usually it is the Web App name\nConnect to Azure SQL Database with PDO PDO (PHP Data Objects) is a database access layer in PHP that provides a uniform and secure way to interact with different databases (MySQL, PostgreSQL, SQL Server, SQLite, etc.).\n1\t$azureServer = \u0026#39;myazureserver.database.windows.net\u0026#39;; 2\t$azureDatabase = \u0026#39;myazuredatabase\u0026#39;; 3\t$connectionInfo = array(\u0026#39;Database\u0026#39;=\u0026gt;$azureDatabase, 4\t\u0026#39;Authentication\u0026#39;=\u0026gt;\u0026#39;ActiveDirectoryMsi\u0026#39;); 5\t$conn = sqlsrv_connect($azureServer, $connectionInfo); 6 7\tif ($conn === false) { 8\techo \u0026#34;Could not connect with Authentication=ActiveDirectoryMsi (system-assigned).\\n\u0026#34;; 9\tprint_r(sqlsrv_errors()); 10\t} else { 11\techo \u0026#34;Connected successfully with Authentication=ActiveDirectoryMsi (system-assigned).\\n\u0026#34;; 12 13\t$tsql = \u0026#34;SELECT @@Version AS SQL_VERSION\u0026#34;; 14\t$stmt = sqlsrv_query($conn, $tsql); 15\tif ($stmt === false) { 16\techo \u0026#34;Failed to run the simple query (system-assigned).\\n\u0026#34;; 17\tprint_r(sqlsrv_errors()); 18\t} else { 19\twhile ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { 20\techo $row[\u0026#39;SQL_VERSION\u0026#39;] . PHP_EOL; 21\t} 22 23\tsqlsrv_free_stmt($stmt); 24\t} 25\tsqlsrv_close($conn); 26\t} To conclude Using a managed identity to connect your frontend application (WebApp) to your backend SQL database eliminates the need for hardcoded usernames and passwords. This approach enhances security by leveraging Azure's identity management, ensuring that credentials are automatically managed and rotated.\n🔥 Advantages of Using Managed Identity\n✅ No hardcoded credentials in code.\n✅ Automatically rotates tokens for security.\n✅ Works across Azure services (VMs, App Service, Functions,etc).\n","link":"https://benoit-gaumard.io/blog/post/24-azure-sql-database-php-connection/","section":"post","tags":["Database","Security","PHP"],"title":"App Service (PHP) access to Azure SQL database with managed identity"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/database/","section":"tags","tags":null,"title":"Database"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/php/","section":"tags","tags":null,"title":"PHP"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/security/","section":"tags","tags":null,"title":"Security"},{"body":"When you create a VM on Azure, the ICMP protocol (Ping) is blocked (Deny) by the Windows Firewall on the VM. This means that by default, you won't be able to ping your VM to check its connectivity. Pinging is a useful tool for diagnosing network issues and ensuring that your VM is reachable.\nIn this article, we will guide you through the steps to allow ICMP (Ping) traffic to your Azure VM by creating a new firewall rule. This can be done either directly within the VM or through the Azure portal's run command feature. Follow the instructions below to enable ICMP (Ping) on your Azure VM.\nTo enable ICMP (Ping) on your VM, execute the following command either directly within the VM or through the Azure portal's run command feature:\n1New-NetFirewallRule -DisplayName \u0026#34;ICMP Allow Ping V4\u0026#34; -Direction Inbound -Protocol ICMPv4 -Action Allow After the script execution completes, you should be able to successfully ping your VM.\nEnjoy!\n","link":"https://benoit-gaumard.io/blog/post/22-allow-icmp-windows-vm/","section":"post","tags":["vm","iaas"],"title":"Allow ICMP (Ping) on Azure VM"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/iaas/","section":"tags","tags":null,"title":"Iaas"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/network/","section":"tags","tags":null,"title":"Network"},{"body":"Do you want to restrict access to your Web App to specific users or groups within your organization? (which is by default enabled for all the users in the tenant).\nNetwork security perimeter (NSP) allows organizations to define a logical network isolation boundary for PaaS resources (for example, Azure Storage account and SQL Database server) that are deployed outside your organization’s virtual networks. It restricts public network access to PaaS resources within the perimeter; access can be exempted by using explicit access rules for public inbound and outbound.\nOfficial Microsoft documentation: https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-concepts\nPain points Inconsistent access controls: PaaS services have partial and inconsistent inbound access controls. Varied user experience: Access control mechanisms differ across services (Portal, API, CLI, etc.). Scalability challenges: Managing compliance and auditing is complex, requiring custom Azure Policies for each service. Existing patterns Here are the existing patterns to avoid public endpoints and to secure access:\nVNet Injection/Integration: This allows service instances to run inside the customer's VNet, providing better control and security.\nhttps://learn.microsoft.com/en-us/azure/virtual-network/vnet-integration-for-azure-services Private Link / Private Endpoint: These are used for services running outside the customer's VNet, ensuring secure and private access.\nhttps://learn.microsoft.com/en-us/azure/private-link/private-link-service-overview Network Access Control features in Azure Here are the features available on Azure:\nNetwork Security Group (NSG) Azure Firewall Network Rule Azure Virtual Network Manager (AVNM) Admin Rule Network Security Perimeter (Private Preview) Azure Network Security Perimeter (NSP)For PaaS Resources Centrally manage your ACLs Centralized mechanism for Access Controls (PaaS) During Microsoft Ignite 2024, Microsoft announced the public preview of Network Security Perimeter. What is a network security perimeter? | Microsoft Learn A game changer for the future PaaS services only Maybe one day all features will be here API: Microsoft.Network/networkSecurityPerimeters IAC: Bicep / ARM / Terraform (No provider, no module / AZ API only) Overview Without Network Security Perimeter: Firewall Rules On Every Resource / One firewall rule per resource With Network Security Perimeter: Access Rules /One access rule to secure all the resources Deployment Deploy from Azure portal Create Inbound and Outbound rules Associate resources Modify associated resource (If needed) Conclusion","link":"https://benoit-gaumard.io/blog/post/23-network-security-perimeter/","section":"post","tags":["Network","Security"],"title":"Network Security Perimeter (NSP)"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/vm/","section":"tags","tags":null,"title":"Vm"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/entra-id/","section":"tags","tags":null,"title":"Entra Id"},{"body":"Do you want to restrict access to your Web App to specific users or groups within your organization? (which is by default enabled for all the users in the tenant).\nThis post will guide you on how to use Microsoft Entra ID to secure your web app by managing authentication and authorization for users or security groups.\nYou can restrict the user completely to not grant access to the application in Entra Id by checking the \u0026quot;Assignment required\u0026quot; box in your Enterprise application properties.\nFrom Entra Id search \u0026quot;Enterprise Applications\u0026quot; ans search your application by name or id.\nSwitch over to \u0026quot;Users and groups\u0026quot; to assign specific users or groups to this app.\nNow only the above assigned users or group members are allowed to access the application.\nNot authorized users will have the following error message when accessing to the application:\nEnjoy!\n","link":"https://benoit-gaumard.io/blog/post/21-authentication-restrict-access-to-azure-web-app/","section":"post","tags":["Entra Id","Web App"],"title":"Restrict Web App acess authentication"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/web-app/","section":"tags","tags":null,"title":"Web App"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/bicep/","section":"tags","tags":null,"title":"Bicep"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/terraform/","section":"tags","tags":null,"title":"Terraform"},{"body":"Terraform Vs Bicep. What truly matters when working with Azure is deciding whether Terraform or Bicep is the right choice for your needs.\nVS For the past few years, my professional focus has been on developing Infrastructure-as-Code and CI/CD pipelines for various Azure customers. Through this, I've gained hands-on experience with both Terraform and Bicep.\nI would like to share my perspective on the topic.\n🟢 Green bullets highlight positive points.\n🔴 Red bullets indicate negative points.\n🟠 Orange bullets represent neutral or mixed points.\nFeature Terraform Bicep Language 🟠 HCL 🟢 JSON Multi provider 🟢 Yes 🔴 No Editor 🟢 Hashicorp 🟢 Microsoft Age 🟢 2014 🟠2020 State Management 🔴 Yes 🟢 No Native 🔴 No 🟢 Yes Learning Curve 🟠 Moderate 🟢 Easy Modules 🟢 Yes 🟢 Yes Logging 🟠 Moderate 🟢 Portal Advanced features 🟢 Yes 🟠 Moderate Support outside changes 🔴 No 🟢 Yes VS Code integration 🟢 Yes 🟢 Yes CI /CD 🟢 Yes 🟢 Yes Adoption 🟢 High 🟠 Moderate Cost 🟠 Free / Licence 🟢 Free Language Terraform: Uses its own declarative HashiCorp Configuration Language (HCL), which is cloud-agnostic. Bicep: Simplified syntax designed to work exclusively with Azure, serving as an abstraction over ARM JSON templates. Multi provider Terraform: A multi-cloud Infrastructure as Code (IaC) tool designed for provisioning resources across various cloud platforms. Multi-cloud support (Azure, AWS, GCP, etc.), enabling hybrid cloud deployments. Bicep: A domain-specific IaC tool for deploying Azure resources, designed as a simplified alternative to Azure Resource Manager (ARM) templates. Azure-only, deeply integrated with the Azure ecosystem. Editors Terraform: HashiCorp in 2014 Bicep: Microsoft in 2020 State Management Terraform: Requires a state file to track resource changes; supports remote state storage (e.g., Azure Blob Storage, S3). Bicep: Stateless; relies on Azure Resource Manager's existing state, eliminating the need for a separate state file. Learning Curve Terraform: Slightly steeper learning curve due to HCL and the need to manage state files. Bicep: Easier for those already familiar with Azure, thanks to simpler syntax and Azure-specific focus. Modularity Terraform: Supports modules for reusable code, which can be shared across clouds. Highly extensible through custom providers and community plugins Bicep: Supports modules, but limited to Azure-specific scenarios. Limited to Azure-specific extensions and features. Maturity Terraform: Mature and widely adopted, with a large user base and community support. Bicep: Newer, rapidly evolving, but designed as the preferred way to manage Azure resources. Cost Terraform: Terraform is open-source but also offers paid enterprise features, such as Terraform Cloud, which facilitates team collaboration and advanced capabilities. Recently, HashiCorp’s licensing model changed to the Business Source License (BSL), leading to the creation of a community-driven fork called OpenTofu, which adheres to a fully open-source model to maintain its compatibility and broader accessibility. Bicep: Completely free, part of the Azure tooling suite. To conclude In conclusion, there is no \u0026quot;IaC war\u0026quot;—both tools have their strengths. For many use cases, I prefer Bicep over Terraform, particularly in scenarios where no one else will manage the IaC or to sidestep chicken-and-egg challenges, such as provisioning the storage account used for Terraform’s state.\nFor other use cases, I’ll stick with Terraform as it keeps people aligned with a consistent, multi-cloud approach and provides robust state management, making it ideal for more complex or diverse infrastructure scenarios. Additionally, the Terraform community is currently more established and active than the Bicep community, largely due to the longer maturity of the product.\nEnjoy!\n","link":"https://benoit-gaumard.io/blog/post/20-terraform-vs-bicep/","section":"post","tags":["Terraform","Bicep"],"title":"Terraform vs Bicep, the match"},{"body":"Here is a simple method to display GitHub secrets for debugging purposes.\nUsing this command line:\n1run: echo ${{ secrets.MYSECRET}} | sed \u0026#39;s/./\u0026amp; /g\u0026#39; Here is an example workflow below:\n1name: Print GitHub Secrets 2 3on: 4 push: 5 6jobs: 7 print_secrets: 8 runs-on: ubuntu-latest 9 steps: 10 - name: Debug secret in variable 11 run: echo ${{ secrets.MYSECRET}} | sed \u0026#39;s/./\u0026amp; /g\u0026#39; Danger This method is intended solely for debugging purposes. Avoid using it in production environments and never expose secrets in your pipelines!\n","link":"https://benoit-gaumard.io/blog/post/19-display-github-secrets-for-debug/","section":"post","tags":["github"],"title":"Display GitHub secrets for debug"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/policies/","section":"tags","tags":null,"title":"Policies"},{"body":"If you want to create your own or contribute to an existing GitHub project, you are on the right page.\nIntroduction Many companies have big infrastructures, but often overlook the organization of their resources in Azure. This oversight can make simple tasks, such as tracking, unnecessarily complicated just because resources weren't properly organized.\nWith Azure resource tagging, you can assign metadata to your resources, making it easy to filter and locate resources that share the same tag!\nThis script has been forked and updated from: Using Azure tags to improve resources organization | by Amine Charot | Charot | Medium\nWhat is a tag? A tag is a Key/Value pair. It can be applied to the resource groups or Directly on the resources. It is searchable so it can be used to find resources or resource groups using Powershell or Azure Portal …\nMicrosoft official documentation is available here: Tag resources, resource groups, and subscriptions for logical organization - Azure Resource Manager | Microsoft Learn\nUsing the PowerShell command:\n1(Get-AzResource -Tag @{ Environment=\u0026#34;PROD\u0026#34;}).Name It will return all the resources that contain the PROD tag. You can separate costs based on a tag name, so the tags in Azure may be useful for billing information.\nCommon tags Environment : The environment which may be sandbox, dev or prod …\nCreatedBy : The person who creates the resource.\nCreationDate : When the resource has been created.\nime To Live : If it is a temporary resource, how much time it must live.\nCriticality : The importance of the resource.\nNote : The creation date may be useful if you want to find all the resources created on the same day.\nTemporary resources use case Tags can be incredibly useful for automation. For example, if you have temporary resources, you can apply a \u0026quot;Time To Live\u0026quot; (TTL) tag to them.\nIn this scenario, you can create a storage account and assign it a \u0026quot;Time To Live\u0026quot; tag. Once the TTL is exceeded, the storage account can be automatically deleted.\nIn this case, the CreationDate tag date format is: dd-MM-yy\nBy using a PowerShell script, you can automate the process of finding and deleting all temporary resources based on their \u0026quot;TTL\u0026quot; tag.\nThis script will find all the resources that contain a “TTL” tag, it will compare the current date with the creation one. If the difference between them is greater than the TTL so we remove the resource.\nUsing these tags, it will be easier for you to purge the old resources.\nNow if we want to remove all the expired resources, we just have to run the script :\n1$resources = Get-AzResource|Where-Object {$_.tags.keys -match \u0026#34;TTL\u0026#34;} 2$currentDate = Get-Date -format \u0026#34;dd-MM-yy\u0026#34; 3$resources.foreach{ 4 $creationDate = Get-Date $PSItem.tags[\u0026#34;CreationDate\u0026#34;] 5 $days = (New-TimeSpan -Start $creationDate -End $currentDate).days 6 $difDays = $PSItem.tags[\u0026#34;TTL\u0026#34;] - $days 7 if($difDays -le 0) 8 { 9 $resourceName = $PSItem.Name 10 Write-Output \u0026#34;Remove the resource $resourceName\u0026#34; 11 Remove-AzResource -ResourceId $PSItem.ResourceId -Force 12 } 13} Automatically add tag CreatedBy use case Some tags (like the Time To Live, Criticality or createdDate) may be added on creation.\nFor untagged or legacy resources without “CreatedBy” can be added automatically using a script.\nThis script will get all the resources and for every untagged one, it will apply a “CreatedBy” Tag.\n1$resources = Get-AzResource 2 3$currentTime = Get-Date 4$endTime = $currentTime.AddDays(-7 * $cnt) 5$startTime = $endTime.AddDays(-7) 6 7$resources.foreach{ 8 $untaggedResources = $PSItem.tags[\u0026#34;CreatedBy\u0026#34;] 9 if($untaggedResources -eq $null) 10 { 11 $owner = Get-AzLog -ResourceId $PSItem.ResourceId -StartTime $startTime -EndTime $endTime | Where {$_.Authorization.Action -like \u0026#34;*/write*\u0026#34;} | 12 Select -ExpandProperty Caller | 13 Group-Object | 14 Sort-Object | 15 Select -ExpandProperty Name 16 $PSItem.Tags.Add(\u0026#34;CreatedBy\u0026#34;, $owner) 17 $PSItem | Set-AzResource -Force 18 } 19 20} Enjoy!\n","link":"https://benoit-gaumard.io/blog/post/17-remove-old-resources-based-on-tags/","section":"post","tags":["tags"],"title":"Remove old Azure resources based on tags"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nUse this script to quickly find and search for supported Azure Policy Aliases https://docs.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure#aliases to use when authoring custom Azure Policy definitions.\nSelect one or more namespaces from the list –\u0026gt; Click OK\nAnd then you will have all available aliases for the selected resources:\nHere is the script:\n1# List all namespaces available in Azure Policy 2$AllNamespaces = (Get-AzPolicyAlias -ListAvailable).Namespace | Sort-Object | Get-Unique 3 4# Select the namespaces you want to work with 5$SelectedNamespaces = $null 6$SelectedNamespaces = @() 7 8$AllNamespaces | Out-GridView -Title \u0026#34;Select one or more namespace. Found: $($AllNamespaces.count)\u0026#34; -OutputMode Multiple ` 9| Foreach-object { $SelectedNamespaces += $_ } 10 11# Get all aliases available in the selected namespaces 12$AvailableAliases = $null 13$AvailableAliases = @() 14 15Foreach ($Namespace in $SelectedNamespaces) 16{ 17 $AvailableAliases += (Get-AzPolicyAlias -NamespaceMatch $Namespace).Aliases | Select-Object Name, DefaultPath 18} 19 20# List all aliases available in the selected namespaces 21$AvailableAliases | Out-GridView -Title \u0026#34;Available alias for selected ($($SelectedNamespaces.count)): $($SelectedNamespaces)\u0026#34; -OutputMode Single ","link":"https://benoit-gaumard.io/blog/post/18-search-azure-policy-aliases/","section":"post","tags":["policies"],"title":"Search Azure policy aliases and sends output to an interactive table"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/tags/","section":"tags","tags":null,"title":"Tags"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nYou probably wouldn’t furnish a house you’re building with a state of the art entertainment system without first installing doors and an alarm system. Similarly, it isn’t advisable to put valuable applications and data used to run your business in the cloud without ensuring the proper foundational security and governance controls are in place.\nMany organizations struggle with how they want their cloud home to look, often so anxious to move that proper planning is ignored. Whether adopting PaaS, IaaS, or SaaS, properly planned governance and security foundations are key to ensuring a protected and controlled environment.\nCloud home Critical Design Areas Key components Cloud Adoption Framework (CAF) Landing zone Management groups Policies Built-In vs custom Audit / Deny / If Not exist Automation Azure DevOps vs GitHub RBAC Least privileges\nGroups instead of direct user assigments\nNaming convention Define a naming convention before any deployment Exemple of naming convention Implement a naming policy to enforce the naming convention, ensuring consistency and preventing deviations or poor practices. Tagging Main tags (Env, CreationDate, ...) Implement a tagging policy to enforce the naming convention, ensuring consistency and preventing deviations or poor practices. Network Hub and spoke topology Ip adress plan Peering IPAM VMS NAT Extra tools Az Goviz\nNaming convention tool\n","link":"https://benoit-gaumard.io/blog/post/9-dont-build-your-cloud-home-on-shaky-foundations/","section":"post","tags":["governance"],"title":"✨ Don’t build your cloud home on shaky foundations"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nQuery Language (KQL) Query Collection Query Language (KQL) is the language used across Azure Resource Graph, Azure Monitor, Azure Data Explorer, and Azure Log Analytics.\nHere is a collection of queries: Resource Graph Queries\n⭐✨ Azure Advisor Service retirement 1advisorresources 2| project id, properties.impact, properties.shortDescription.problem ⭐ AKS List node pools 1Resources 2| where type == \u0026#34;microsoft.containerservice/managedclusters\u0026#34; 3| extend nodepools = properties.agentPoolProfiles 4| mv-expand nodepools 5| project name, nodepools.name, nodepools.vmSize, nodepools.minCount, nodepools.maxCount, nodepools.powerState.code, nodeCount = tostring(nodepools[\u0026#39;count\u0026#39;]) 6| sort by name List nodes pools2 1Resources 2| where type == \u0026#34;microsoft.containerservice/managedclusters\u0026#34; 3| extend properties.agentPoolProfiles 4| project subscriptionId, name, pool = (properties.agentPoolProfiles) 5| mv-expand pool 6| project subscription = subscriptionId, cluster = name, size = pool.vmSize, count = pool.[\u0026#39;count\u0026#39;] Get Node pools information 1resources 2| where type == \u0026#34;microsoft.containerservice/managedclusters\u0026#34; 3| extend properties.agentPoolProfiles 4| project subscriptionId, name, nodePool = properties.agentPoolProfiles 5| mv-expand nodePool 6| project subscriptionId, name, sku = nodePool.vmSize, count = nodePool.[\u0026#39;count\u0026#39;], powerState = nodePool.powerState.code ⭐ Disks Get Premium Disks 1resources 2| where type =~ \u0026#39;microsoft.compute/disks\u0026#39; 3| extend skuName=tostring(sku.name) 4| extend accountType=case(skuName =~ \u0026#39;Standard_LRS\u0026#39;, \u0026#39;Standard HDD LRS\u0026#39;, 5 skuName =~ \u0026#39;StandardSSD_LRS\u0026#39;, \u0026#39;Standard SSD LRS\u0026#39;, 6 skuName =~ \u0026#39;UltraSSD_LRS\u0026#39;, \u0026#39;Ultra disk LRS\u0026#39;, 7 skuName =~ \u0026#39;Premium_LRS\u0026#39;, \u0026#39;Premium SSD LRS\u0026#39;, 8 skuName =~ \u0026#39;Standard_ZRS\u0026#39;, \u0026#39;Zone-redundant\u0026#39;, 9 skuName =~ \u0026#39;Premium_ZRS\u0026#39;, \u0026#39;Premium SSD ZRS\u0026#39;, 10 skuName =~ \u0026#39;StandardSSD_ZRS\u0026#39;, \u0026#39;Standard SSD ZRS\u0026#39;, 11 skuName) 12| where accountType contains \u0026#34;Premium\u0026#34; Get SSD Disks 1resources 2| where type =~ \u0026#39;microsoft.compute/disks\u0026#39; 3| extend skuName=tostring(sku.name) 4| extend accountType=case(skuName =~ \u0026#39;Standard_LRS\u0026#39;, \u0026#39;Standard HDD LRS\u0026#39;, 5 skuName =~ \u0026#39;StandardSSD_LRS\u0026#39;, \u0026#39;Standard SSD LRS\u0026#39;, 6 skuName =~ \u0026#39;UltraSSD_LRS\u0026#39;, \u0026#39;Ultra disk LRS\u0026#39;, 7 skuName =~ \u0026#39;Premium_LRS\u0026#39;, \u0026#39;Premium SSD LRS\u0026#39;, 8 skuName =~ \u0026#39;Standard_ZRS\u0026#39;, \u0026#39;Zone-redundant\u0026#39;, 9 skuName =~ \u0026#39;Premium_ZRS\u0026#39;, \u0026#39;Premium SSD ZRS\u0026#39;, 10 skuName =~ \u0026#39;StandardSSD_ZRS\u0026#39;, \u0026#39;Standard SSD ZRS\u0026#39;, 11 skuName) 12| where accountType contains \u0026#34;SSD\u0026#34; Get ZRS Disks 1resources 2| where type =~ \u0026#39;microsoft.compute/disks\u0026#39; 3| extend skuName=tostring(sku.name) 4| extend accountType=case(skuName =~ \u0026#39;Standard_LRS\u0026#39;, \u0026#39;Standard HDD LRS\u0026#39;, 5 skuName =~ \u0026#39;StandardSSD_LRS\u0026#39;, \u0026#39;Standard SSD LRS\u0026#39;, 6 skuName =~ \u0026#39;UltraSSD_LRS\u0026#39;, \u0026#39;Ultra disk LRS\u0026#39;, 7 skuName =~ \u0026#39;Premium_LRS\u0026#39;, \u0026#39;Premium SSD LRS\u0026#39;, 8 skuName =~ \u0026#39;Standard_ZRS\u0026#39;, \u0026#39;Zone-redundant\u0026#39;, 9 skuName =~ \u0026#39;Premium_ZRS\u0026#39;, \u0026#39;Premium SSD ZRS\u0026#39;, 10 skuName =~ \u0026#39;StandardSSD_ZRS\u0026#39;, \u0026#39;Standard SSD ZRS\u0026#39;, 11 skuName) 12| where accountType contains \u0026#34;ZRS\u0026#34; Sort Disks By Size IOPS 1resources 2| where type == \u0026#34;microsoft.compute/disks\u0026#34; 3| project Disk_name=name, SKU=sku.name, Size=strcat(properties[\u0026#39;diskSizeGB\u0026#39;],\u0026#34;GB\u0026#34;), IOPS=tolong(properties[\u0026#39;diskIOPSReadWrite\u0026#39;]) 4| sort by Size ⭐ Frontdoor Routing rules and accepted protocols 1resources 2| where type == \u0026#34;microsoft.network/frontdoors\u0026#34; 3| project subscriptionId, frontDoorName=name, routingRules = (properties.routingRules) 4| mv-expand routingRules 5| project subscriptionId, frontDoorName, routingRuleName=routingRules.name, protocols = routingRules.properties ⭐ Network List all subnets with delegation 1resources 2| where type == \u0026#34;microsoft.network/virtualnetworks\u0026#34; 3| project vnetName = name, subnets = (properties.subnets) 4| mvexpand subnets 5| extend subnetName = (subnets.name) 6| extend isDelegated = isnotnull(subnets.properties.delegations) and array_length(subnets.properties.delegations) != 0 7| where isDelegated == 1 8| project vnetName, subnetName List subnets without NSG 1resources 2| where type == \u0026#34;microsoft.network/virtualnetworks\u0026#34; 3| project vnetName = name, subnets = (properties.subnets) 4| mvexpand subnets 5| extend subnetName = (subnets.name) 6| extend hasNSG = isnotnull(subnets.properties.networkSecurityGroup) 7| where hasNSG == 0 8| project vnetName, subnetName List subnets with service endpoint 1resources 2| where type == \u0026#34;microsoft.network/virtualnetworks\u0026#34; 3| project vnetName = name, subnets = (properties.subnets) 4| mvexpand subnets 5| extend subnetName = (subnets.name) 6| extend hasServiceEndpoints = isnotnull(subnets.properties.serviceEndpoints) and array_length(subnets.properties.serviceEndpoints) != 0 7| where hasServiceEndpoints == 1 8| project vnetName, subnetName List subnet with UDR 1resources 2| where type == \u0026#34;microsoft.network/virtualnetworks\u0026#34; 3| project vnetName = name, subnets = (properties.subnets) 4| mvexpand subnets 5| extend subnetName = (subnets.name) 6| extend hasRouteTable = isnotnull(subnets.properties.routeTable) 7| where hasRouteTable == 1 8| project vnetName, subnetName Subnet IP usage 1resources 2| where type == \u0026#34;microsoft.network/virtualnetworks\u0026#34; 3| project vnetName = name, subnets = (properties.subnets) 4| mvexpand subnets 5| extend subnetName = (subnets.name) 6| extend mask = split(subnets.properties.addressPrefix, \u0026#39;/\u0026#39;, 1)[0] 7| extend usedIp = array_length(subnets.properties.ipConfigurations) 8| extend totalIp = case(mask == 29, 3, 9 mask == 28, 11, 10 mask == 27, 27, 11 mask == 26, 59, 12 mask == 25, 123, 13 mask == 24, 251, 14 mask == 23, 507, 15 mask == 22, 1019, 16 mask == 21, 2043, 17 mask == 20, 4091, 18 mask == 19, 8187, 19 mask == 18, 16379, 20 mask == 17, 32763, 21 mask == 16, 65531, 22 mask == 15, 131067, 23 mask == 14, 262139, 24 mask == 13, 524283, 25 mask == 12, 1048571, 26 mask == 11, 2097147, 27 mask == 10, 4194299, 28 mask == 9, 8388603, 29 mask == 8, 16777211, 30 -1) 31| extend availableIp = totalIp - usedIp 32| project vnetName, subnetName, mask, usedIp, totalIp, availableIp, subnets 33| order by toint(mask) desc ⭐ Resources Display last resources changes since the last week 1resourcechanges 2| extend changeTime = todatetime(properties.changeAttributes.timestamp), 3targetResourceId = tostring(properties.targetResourceId), 4changeType = tostring(properties.changeType), changedBy = tostring(properties.changeAttributes.changedBy), 5changedByType = properties.changeAttributes.changedByType, 6clientType = tostring(properties.changeAttributes.clientType) 7| where changeTime \u0026gt; ago(7d) 8| project changeType, changedBy, changedByType, clientType 9| summarize count() by changedBy, changeType, clientType 10| order by count_ desc ⭐ Resources Groups Display Empty Resource Groups 1ResourceContainers 2| where type == \u0026#39;microsoft.resources/subscriptions/resourcegroups\u0026#39; 3| extend rgAndSub = strcat(resourceGroup, \u0026#39;--\u0026#39;, subscriptionId) 4| join kind=leftouter ( 5 Resources 6 | extend rgAndSub = strcat(resourceGroup, \u0026#39;--\u0026#39;, subscriptionId) 7 | summarize count() by rgAndSub 8) on rgAndSub 9| where isnull(count_) ⭐ Policies Find unused custom policies 1policyresources 2| where type == \u0026#34;microsoft.authorization/policydefinitions\u0026#34; 3| extend policyType = tostring(properties.policyType) 4| where policyType == \u0026#34;Custom\u0026#34; 5| join kind=leftouter ( 6 policyresources 7 | where type == \u0026#34;microsoft.authorization/policysetdefinitions\u0026#34; 8 | extend policyType = tostring(properties.policyType) 9 | extend policyDefinitions = properties.policyDefinitions 10 | where policyType == \u0026#34;Custom\u0026#34; 11 | mv-expand policyDefinitions 12 | extend policyDefinitionId = tostring(policyDefinitions.policyDefinitionId) 13 | project associedIdToInitiative=policyDefinitionId 14 | distinct associedIdToInitiative) on $left.id == $right.associedIdToInitiative 15| where associedIdToInitiative == \u0026#34;\u0026#34; 16| join kind=leftouter( 17 policyresources 18 | where type == \u0026#34;microsoft.authorization/policyassignments\u0026#34; 19 | extend policyDefinitionId = tostring(properties.policyDefinitionId) 20 | project associatedDefinitionId=policyDefinitionId 21 | distinct associatedDefinitionId 22) on $left.id == $right.associatedDefinitionId 23| where associatedDefinitionId == \u0026#34;\u0026#34; 24| extend displayName = tostring(properties.displayName) 25| project id, displayName Count policies assignment by scope 1policyresources 2| where type == \u0026#34;microsoft.authorization/policyassignments\u0026#34; 3| extend scope = tostring(properties.scope) 4| summarize count() by scope 5| order by count_ desc Count custom policies assignments by scope 1policyresources 2| where type == \u0026#34;microsoft.authorization/policydefinitions\u0026#34; 3| extend policyType = tostring(properties.policyType) 4| where policyType == \u0026#34;Custom\u0026#34; 5| project id 6| extend scope = tostring(split(id, \u0026#34;/providers/Microsoft.Authorization/policyDefinitions/\u0026#34;, 0)[0]) 7| summarize count() by scope 8| order by count_ desc ⭐ RBAC List user direct assignment at management group level 1authorizationresources 2| extend scope = tostring(properties.scope) 3| join kind = inner ( 4 resourcecontainers 5 | where type == \u0026#34;microsoft.management/managementgroups\u0026#34; 6 | project managementGroupId=id, managementGroupName=properties.displayName 7) on $right.managementGroupId == $left.scope 8| where properties.principaltype == \u0026#34;User\u0026#34; 9| project properties.createdOn, managementGroupName, scope, managementGroupId List user assignment at subscription level 1authorizationresources 2| join kind = inner ( 3 resourcecontainers 4 | where type == \u0026#34;microsoft.resources/subscriptions\u0026#34; 5 | project subscriptionName=name, subscriptionId) on subscriptionId 6| where type == \u0026#34;microsoft.authorization/roleassignments\u0026#34; 7| where properties.principalType == \u0026#34;User\u0026#34; 8| project properties.createdOn, properties.scope, properties.principalId, subscriptionId All RBAC Assignments 1authorizationresources 2| where type =~ \u0026#39;microsoft.authorization/roleassignments\u0026#39; 3| extend roleDefinitionId= tolower(tostring(properties.roleDefinitionId)) 4| extend principalType = properties.principalType 5| extend principalId = properties.principalId 6| extend description = properties.description 7| extend scope = properties.scope 8| extend createdBy = properties.createdBy 9| join kind = inner ( 10authorizationresources 11| where type =~ \u0026#39;microsoft.authorization/roledefinitions\u0026#39; 12| extend roleDefinitionId = tolower(id) 13| extend roleName = tostring(properties.roleName) 14| extend roleType = tostring(properties.type) 15| project roleDefinitionId,roleName,roleType 16) on roleDefinitionId 17| project principalId,principalType,createdBy,description,roleName,roleType,scope,roleDefinitionId ⭐ Resource Groups Display Empty Resource Groups 1ResourceContainers 2| where type == \u0026#39;microsoft.resources/subscriptions/resourcegroups\u0026#39; 3| extend rgAndSub = strcat(resourceGroup, \u0026#39;--\u0026#39;, subscriptionId) 4| join kind=leftouter ( 5 Resources 6 | extend rgAndSub = strcat(resourceGroup, \u0026#39;--\u0026#39;, subscriptionId) 7 | summarize count() by rgAndSub 8) on rgAndSub 9| where isnull(count_) ⭐ Resource changes Display last resources changes since the last week 1resourcechanges 2| extend changeTime = todatetime(properties.changeAttributes.timestamp), 3targetResourceId = tostring(properties.targetResourceId), 4changeType = tostring(properties.changeType), changedBy = tostring(properties.changeAttributes.changedBy), 5changedByType = properties.changeAttributes.changedByType, 6clientType = tostring(properties.changeAttributes.clientType) 7| where changeTime \u0026gt; ago(7d) 8| project changeType, changedBy, changedByType, clientType 9| summarize count() by changedBy, changeType, clientType 10| order by count_ desc ⭐ Service Health Display by Impacted resource Id 1servicehealthresources 2| where type == \u0026#34;microsoft.resourcehealth/events/impactedresources\u0026#34; 3| extend TrackingId = split(split(id, \u0026#34;/events/\u0026#34;, 1)[0], \u0026#34;/impactedResources\u0026#34;, 0)[0] 4| extend p = parse_json(properties) 5| project subscriptionId, TrackingId, targetResourceId= tostring(p.targetResourceId), details = p 6| join kind=inner ( 7 resources 8 ) 9 on $left.targetResourceId == $right.id Display by Events (TrackingId) 1ServiceHealthResources 2| where type =~ \u0026#39;Microsoft.ResourceHealth/events\u0026#39; 3| extend eventType = tostring(properties.EventType), status = properties.Status, description = properties.Title, trackingId = properties.TrackingId, summary = properties.Summary, priority = properties.Priority, impactStartTime = properties.ImpactStartTime, impactMitigationTime = properties.ImpactMitigationTime, 4EventSubType = properties.EventSubType 5| mv-expand Impact = properties.Impact 6| extend ImpactedService = Impact.ImpactedService 7| where eventType == \u0026#39;HealthAdvisory\u0026#39; and status == \u0026#39;Active\u0026#39; and EventSubType == \u0026#39;Retirement\u0026#39; 8| summarize count(subscriptionId) by name 9| order by [\u0026#39;count_subscriptionId\u0026#39;] desc Display by Events (TrackingId) and Resource Id impacted 1// Filter Specific Tracking IDs and Combine Health Advisory with Impacted Resources 2servicehealthresources 3| where type =~ \u0026#39;Microsoft.ResourceHealth/events\u0026#39; 4| extend 5 eventType = properties.EventType, 6 EventSubType = properties.EventSubType, 7 status = properties.Status, 8 description = properties.Title, 9 trackingId = tostring(properties.TrackingId), // Explicitly cast TrackingId to string 10 summary = properties.Summary, 11 priority = properties.Priority, 12 impactStartTime = properties.ImpactStartTime, 13 impactMitigationTime = properties.ImpactMitigationTime 14| mv-expand Impact = properties.Impact 15| extend ImpactedService = Impact.ImpactedService 16//| where eventType == \u0026#39;HealthAdvisory\u0026#39; and status == \u0026#39;Active\u0026#39; and EventSubType == \u0026#39;Retirement\u0026#39; 17| where eventType == \u0026#39;PlannedMaintenance\u0026#39; and status == \u0026#39;Active\u0026#39; 18| join kind=inner ( 19 servicehealthresources 20 | where type == \u0026#34;microsoft.resourcehealth/events/impactedresources\u0026#34; 21 | extend TrackingId = tostring(split(split(id, \u0026#34;/events/\u0026#34;, 1)[0], \u0026#34;/impactedResources\u0026#34;, 0)[0]) // Explicitly cast TrackingId to string 22 | extend p = parse_json(properties) 23 | project subscriptionId, TrackingId, targetResourceId = tostring(p.targetResourceId), details = p 24) on $left.trackingId == $right.TrackingId 25| project 26 trackingId, 27 subscriptionId, 28 ImpactedService, 29 targetResourceId, 30 description, 31 summary, 32 priority, 33 impactStartTime, 34 impactMitigationTime, 35 details ⭐ Storage Accounts Count Storage accounts by sku 1resources 2| where type == \u0026#34;microsoft.storage/storageaccounts\u0026#34; 3| extend sku = sku.name 4| summarize count(name) by tostring(sku) ⭐ Subscriptions List subscriptions part of an EA 1resourcecontainers 2| where type == \u0026#34;microsoft.resources/subscriptions\u0026#34; 3| where properties.state == \u0026#34;Enabled\u0026#34; 4| mv-expand subscriptionPolicies = properties.subscriptionPolicies 5| where name !contains \u0026#34;Visual Studio\u0026#34; and subscriptionPolicies.quotaId startswith \u0026#34;MSDNDevTest\u0026#34; or subscriptionPolicies.quotaId startswith \u0026#34;EnterpriseAgreement\u0026#34; List subscriptions by MG 1ResourceContainers 2| where type =~ \u0026#39;microsoft.resources/subscriptions\u0026#39; 3| extend mgParent = properties.managementGroupAncestorsChain 4| mv-expand with_itemindex=MGHierarchy mgParent 5| project subscriptionId, name, mgParent, MGHierarchy, mgParent.name Count subscriptions by MG 1ResourceContainers 2| where type =~ \u0026#39;microsoft.management/managementgroups\u0026#39; 3| project mgname = name 4| join kind=leftouter (resourcecontainers | where type=~ \u0026#39;microsoft.resources/subscriptions\u0026#39; 5| extend mgParent = properties.managementGroupAncestorsChain | project id, mgname = tostring(mgParent[0].name)) on mgname 6| summarize count() by mgname Count all subscriptions by tenant 1ResourceContainers 2| where type =~ \u0026#39;microsoft.resources/subscriptions\u0026#39; 3| project SubscriptionName=name, subscriptionId, tenantId 4| summarize count() by tenantId 5| order by [\u0026#39;count_\u0026#39;] desc List resources part of a list of subscriptions 1resources 2| where subscriptionId in (\u0026#34;subid1-xxx-xxx-xxx-xxx\u0026#34;, \u0026#34;subid2-xxx-xxx-xxx-xxx\u0026#34;, \u0026#34;subid3-xxx-xxx-xxx-xxx\u0026#34;, \u0026#34;subid4-xxx-xxx-xxx-xxx\u0026#34;) Check subscription naming convention 1resourcecontainers 2| where type == \u0026#34;microsoft.resources/subscriptions\u0026#34; 3| where properties.state == \u0026#39;Enabled\u0026#39; 4| extend NamingCheck = iff((name startswith \u0026#39;sub-\u0026#39;),\u0026#34;Naming is OK\u0026#34;,\u0026#34;Naming is not OK\u0026#34;) 5| summarize count() by NamingCheck Check subscription naming convention on a specific management group 1resourcecontainers 2| where type == \u0026#34;microsoft.resources/subscriptions\u0026#34; 3| where properties.state == \u0026#39;Enabled\u0026#39; 4| where properties.managementGroupAncestorsChain contains \u0026#39;Production\u0026#39; 5| extend NamingCheck = iff((name startswith \u0026#39;sub-\u0026#39;),\u0026#34;Naming is OK\u0026#34;,\u0026#34;Naming is not OK\u0026#34;) 6| summarize count() by NamingCheck List subscriptions in a specific management group 1resourcecontainers 2 | where type == \u0026#34;microsoft.resources/subscriptions\u0026#34; 3 | where (properties.managementGroupAncestorsChain) contains \u0026#34;Sandbox\u0026#34; Count resources type in a subscription 1resources 2| join kind=leftouter 3 (resourcecontainers 4 | where type == \u0026#39;microsoft.resources/subscriptions\u0026#39; 5 | project subscriptionName=name, subscriptionId) on subscriptionId 6| where subscriptionName == \u0026#34;\u0026lt;your-sub-name-here\u0026gt;\u0026#34; 7| summarize count() by type, subscriptionName Count subscriptions by management groups 1resourcecontainers 2| where type == \u0026#39;microsoft.resources/subscriptions\u0026#39; 3| project subscriptionName = name, managementgroups = (properties.managementGroupAncestorsChain) 4| mv-expand managementgroups 5| summarize count() by tostring(managementgroups.displayName) 6| order by count_ desc ⭐ Tags Resources without tag 1resourcecontainers 2| where type != \u0026#34;microsoft.management/managementgroups\u0026#34; 3| mv-expand bagexpansion=array tags 4| where isempty(tags) Resources with specific tags and expand tag names/values to individual rows 1resourcecontainers 2| where type != \u0026#34;microsoft.management/managementgroups\u0026#34; 3| mvexpand parsejson(tags) 4| extend tagname = tostring(bag_keys(tags)[0]) 5| extend tagvalue = tostring(tags[tagname]) 6| project name,id,type,location,subscriptionId,tagname,tagvalue 7| union (resources 8| mvexpand parsejson(tags) 9| extend tagname = tostring(bag_keys(tags)[0]) 10| extend tagvalue = tostring(tags[tagname]) 11| project name,id,type,location,subscriptionId,tagname,tagvalue) 12| where tagname == \u0026#34;Environment\u0026#34; or tagname == \u0026#34;Owner\u0026#34; Resources not containing a specific tag 1resourcecontainers 2| where tags !contains \u0026#39;Environment\u0026#39; Resources not containing a tag and count 1resourcecontainers 2| where tags !contains \u0026#39;Environment\u0026#39; 3| project name, resourceGroup, subscriptionId, location, tags 4| summarize count () by subscriptionId All tags for resources 1resourcecontainers 2| project name,type,location,subscriptionId,tags 3| union (resources | project name,type,location,subscriptionId,tags) Count for a specific tag key 1ResourceContainers 2| where type =~ \u0026#39;microsoft.resources/subscriptions/resourcegroups\u0026#39; 3| mvexpand tags 4| extend tagKey = tostring(bag_keys(tags)[0]) 5| extend tagValue = tostring(tags[tagKey]) 6| where tagKey == \u0026#34;Environment\u0026#34; 7| summarize count() by tagValue 8| order by [\u0026#39;count_\u0026#39;] desc TEST 1resources 2| where type =~ \u0026#39;Microsoft.Compute/virtualMachines\u0026#39; 3| mvexpand tags 4| extend tagKey = tostring(bag_keys(tags)[0]) 5| extend tagValue = tostring(tags[tagKey]) 6| where tagKey hasprefix \u0026#34;creat\u0026#34; and tagKey hasprefix \u0026#34;cr\u0026#34; 7| project name, tags, tagKey, tagValue ","link":"https://benoit-gaumard.io/blog/post/10-kql-query-collection/","section":"post","tags":["kql"],"title":"✨ KQL query collection"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/api/","section":"tags","tags":null,"title":"API"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nMicrosoft provides a list of all REST APIs (REST API Browser) available for Azure by clicking on the following link: https://docs.microsoft.com/en-us/rest/api/?view=Azure\nFor example, if I take the API dedicated to Compute and select Virtual Machines: https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines\nI will have access to all the actions I can perform on the Virtual Machines object.\nFor example, to list all VMs in an Azure subscription: https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines/listall\nThe major advantage of this site is that it allows live testing of the selected API (by clicking on Try It) from a web browser, without needing to install a third-party tool (such as Postman or others).\nAll Azure APIs return results in JSON format, making them easily exploitable.\nEach Azure API requires passing a mandatory parameter, api-version, to specify the version of the API to use and thus benefit from backward compatibility in case of version changes.\nFirst, install the Az.Resources module:\n1Install-Module -Name Az.Resources In PowerShell, if I want to know the version of the APIs available for a given provider, I need to execute the following command:\n1PowerShellGet-AzResourceProvider -ListAvailable | Select-Object ProviderNamespace -ExpandProperty ResourceTypes | select-object ProviderNamespace, RegistrationState, ResourceTypeName,ApiVersions | ft If I take the Compute provider, I can display the resources with the following command:\n1PowerShell(Get-AzResourceProvider -ProviderNamespace Microsoft.Compute).ResourceTypes And with this command, I can list the available API versions:\n1PowerShell((Get-AzResourceProvider -ProviderNamespace Microsoft.Compute).ResourceTypes | Where-Object ResourceTypeName -eq virtualMachines).ApiVersions So, all those listed are supported. The retention period is quite long, allowing application developers enough time to make necessary modifications without being caught off guard before the API is deprecated.\nEach API has its own lifecycle, and there is no official timeline regarding the retention period of older versions.\n","link":"https://benoit-gaumard.io/blog/post/11-rest-api-versions-and-lifecycle/","section":"post","tags":["API"],"title":"Azure REST API’s, versions, and lifecycle"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nUsing PowerShell or the command line to call an Azure REST API is a quick method to retrieve or update information about a specific resource in Azure. Although Postman can also be used for this purpose, here is an example of how to make these requests using PowerShell.\nFirst, log in to your Azure account with the following command:\n1Connect-AzAccount Set the subscription context if you have multiple subscriptions:\n1Set-AzContext -Subscription \u0026#34;\u0026lt;SubscriptionId\u0026gt;\u0026#34; Get the current token:\n1# Get the current token 2$Token = (Get-AzAccessToken).Token Make the authorization header:\n1# Set the authorization header 2$Headers = @{ 3 Authorization = \u0026#34;Bearer $Token\u0026#34; 4} Define wich resource you want to query. In this example, I want to get properties of my storage account, in a resource group in my subscription.\nTo get the API url and properties, I am using the REST API reference documentation: Azure REST API reference documentation | Microsoft Learn.\nTo construct the API URL I will substitute subscriptionId, resource group, and storage account with proper values.\n1$Uri = \u0026#34;https://management.azure.com/subscriptions/{SubscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}?api-version=2023-01-01\u0026#34; Finally, use Invoke-WebRequest command for the API call:\n1Invoke-WebRequest -Method GET -UseBasicParsing -Uri $Uri -Headers $Headers JSON content of the request for the storage account properties can be accessed with:\n1(Invoke-WebRequest -Method GET -Uri $Uri -Headers $Headers).Content Here is a full code:\n1Connect-AzAccount 2 3Set-AzContext -Subscription \u0026#34;\u0026lt;SubscriptionId\u0026gt;\u0026#34; 4 5# Get the current token 6$Token = (Get-AzAccessToken).Token 7 8# Set the authorization header 9$Headers = @{ 10 Authorization = \u0026#34;Bearer $Token\u0026#34; 11} 12 13$Uri = \u0026#34;https://management.azure.com/subscriptions/{SubscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}?api-version=2023-01-01\u0026#34; 14 15$Result = (Invoke-WebRequest -Method GET -Uri $Uri -Headers $Headers) 16 17If ($Result.StatusCode -eq \u0026#34;200\u0026#34;){ 18 $Result.Content 19} ","link":"https://benoit-gaumard.io/blog/post/7-call-azure-api-with-powershell/","section":"post","tags":["API","Powershell"],"title":"Call Azure API with Powershell"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/governance/","section":"tags","tags":null,"title":"Governance"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/kql/","section":"tags","tags":null,"title":"Kql"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/powershell/","section":"tags","tags":null,"title":"Powershell"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/rbac/","section":"tags","tags":null,"title":"RBAC"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nIf you see the Identiy not found in your RBAC assignments, it means that these identitiy have been deleted from your Entra ID, whether it is a user, a group or a SPN.\nHowever, Azure does not clean up for you, and it’s up to you and it is just ugly in the portal.\nYou must clean-up any orphaned role assignments on a regular basis.\nHere is a Powershell script to clean up:\n1[CmdletBinding()] 2param ( 3 [switch] $CheckOnly, 4 [Parameter(Mandatory = $false)] 5 [string] $Scope = \u0026#34;\u0026#34; 6) 7 8[array]$Assignments = @() 9 10if (\u0026#34;\u0026#34; -eq $Scope) { 11 Write-Output \u0026#34;No Scope defined, getting all assignments.\u0026#34; 12 $Assignments = Get-AzRoleAssignment | Where-Object { $_.ObjectType -eq \u0026#34;Unknown\u0026#34; } 13} else { 14 Write-Output \u0026#34;Scope is: $Scope\u0026#34; 15 $Assignments = Get-AzRoleAssignment -Scope $Scope | Where-Object { $_.ObjectType -eq \u0026#34;Unknown\u0026#34; } 16} 17 18Write-Output \u0026#34;Total: $($Assignments.Count) Unknown Identity found\u0026#34; 19 20Foreach ($Assignment in $Assignments) { 21 22 Write-Output \u0026#34;---------------------------\u0026#34; 23 Write-Output \u0026#34;Scope: $($Assignment.Scope)\u0026#34; 24 Write-Output \u0026#34;Object Type: $($Assignment.ObjectType)\u0026#34; 25 Write-Output \u0026#34;Display Name: $($Assignment.DisplayName)\u0026#34; 26 Write-Output \u0026#34;SignIn Name: $($Assignment.SignInName)\u0026#34; 27 Write-Output \u0026#34;Role Definition Name: $($Assignment.RoleDefinitionName)\u0026#34; 28 Write-Output \u0026#34;Role Definition Id: $($Assignment.RoleDefinitionId)\u0026#34; 29 Write-Output \u0026#34;Role Assignment Id: $($assignment.RoleAssignmentId)\u0026#34; 30 Write-Output \u0026#34;---------------------------\u0026#34; 31 Write-Output \u0026#34;\u0026#34; 32 33 if (-not $CheckOnly) { 34 Write-Output \u0026#34;Removing assignment: $($Assignment.RoleAssignmentId)\u0026#34; 35 $Assignment | Remove-AzRoleAssignment -Verbose 36 } 37 38} ","link":"https://benoit-gaumard.io/blog/post/8-clean-rbac-identity-not-found/","section":"post","tags":["RBAC","Powershell"],"title":"RBAC delete role assignments with 'Identity not found'"},{"body":"If you want to create your own or to contribute to an existing GitHub project you are on the right page.\nThis article presents a PowerShell script that can be used to quickly switch between subscriptions.\nManaging subscriptions can be a challenge in any cloud journey. Here's a script to save you some time. Now can quickly switch between your Azure subscriptions by entering the listed index.\nForked and updated from: matthiasguentert/azure-subscription-switcher (github.com)\n1#azure-subscription-switcher 2Function Switch-AzContext { 3 if (-not (Get-Module -ListAvailable -Name Az.Accounts)) { 4 Write-Host -ForegroundColor Red \u0026#39;Az.Accounts PowerShell module not installed!\u0026#39; 5 return 6 } 7 8 Import-Module Az.Accounts -ErrorAction Stop 9 10 try { 11 # Select only enabled subscriptions and avoid duplicated subscriptions if the user has multiple tenants enrolled with LightHouse 12 $SubscriptionList = Get-AzSubscription | Where-Object { $_.State -eq \u0026#34;Enabled\u0026#34; -and ($_.HomeTenantId -eq $_.TenantId)} | ConvertTo-Json | ConvertFrom-Json 13 } catch { 14 Write-Host -ForegroundColor Red \u0026#34;You have no context, please login first!\u0026#34; 15 return 16 } 17 18 try { 19 $SubscriptionActive = Get-AzContext | ConvertTo-Json | ConvertFrom-Json 20 } catch { 21 Write-Host -ForegroundColor Red \u0026#34;You have no subscription, please login first!\u0026#34; 22 return 23 } 24 25 $available = @() 26 $index = 1 27 $SubscriptionList | ForEach-Object { 28 $available += [PSCustomObject]@{ 29 Active = if ($_.Id -eq $SubscriptionActive.Subscription.Id) { \u0026#34;===\u0026gt;\u0026#34; } else { $null } 30 Index = $index++ 31 Subscription = $_.Name 32 SubscriptionId = $_.Id 33 State = $_.State 34 HomeTenantId = $_.HomeTenantId 35 Account = if ($_.Id -eq $SubscriptionActive.Subscription.Id) { $SubscriptionActive.Account.Id } else { $null } 36 } 37 } 38 39 $available | Format-Table -AutoSize 40 41 try { 42 [int]$userInput = Read-Host \u0026#34;Index (0 to quit)\u0026#34; 43 44 if ($userInput -eq 0) { 45 Write-Host -ForegroundColor Red \u0026#39;Won\u0026#39;\u0026#39;t switch Azure PowerShell context!\u0026#39; 46 return 47 } elseif ($userInput -lt 1 -or $userInput -gt $index-1) { 48 Write-Host -ForegroundColor Red \u0026#34;Input out of range\u0026#34; 49 return 50 } 51 52 $selection = $available | Where-Object { $_.Index -eq $userInput } 53 Write-Host -ForegroundColor Cyan \u0026#39;Switching to:\u0026#39;, $selection.Subscription 54 Set-AzContext -SubscriptionId $selection.SubscriptionId | Out-Null 55 Get-AzContext 56 } catch { 57 Write-Host -ForegroundColor Red \u0026#34;Invalid input, please enter a valid index!\u0026#34; 58 } 59} 60 61Clear-Host 62Switch-AzContext Here is the script output:\nHere is also a version with a user interface (Out-GridView):\n1#azure-subscription-switcher-with-outgridview 2Function Switch-AzContext { 3 if (-not (Get-Module -ListAvailable -Name Az.Accounts)) { 4 Write-Host -ForegroundColor Red \u0026#39;Az.Accounts PowerShell module not installed!\u0026#39; 5 return 6 } 7 8 Import-Module Az.Accounts -ErrorAction Stop 9 10 try { 11 # Select only enabled subscriptions and avoid duplicated subscriptions if the user has multiple tenants enrolled with LightHouse 12 $SubscriptionList = Get-AzSubscription | Where-Object { $_.State -eq \u0026#34;Enabled\u0026#34; -and ($_.HomeTenantId -eq $_.TenantId)} | ConvertTo-Json | ConvertFrom-Json 13 14 } catch { 15 Write-Host -ForegroundColor Red \u0026#34;You have no context, please login first!\u0026#34; 16 return 17 } 18 19 try { 20 $SubscriptionActive = Get-AzContext | ConvertTo-Json | ConvertFrom-Json 21 } catch { 22 Write-Host -ForegroundColor Red \u0026#34;You have no subscription, please login first!\u0026#34; 23 return 24 } 25 26 $available = @() 27 $index = 1 28 $SubscriptionList | ForEach-Object { 29 $available += [PSCustomObject]@{ 30 Active = if ($_.Id -eq $SubscriptionActive.Subscription.id) { \u0026#34;===\u0026gt;\u0026#34; } else { $null } 31 Index = $index++ 32 Subscription = $_.Name 33 SubscriptionId = $_.Id 34 State = $_.State 35 HomeTenantId = $_.HomeTenantId 36 Account = if ($_.Id -eq $SubscriptionActive.Subscription.id) { $SubscriptionActive.Account.id } else { $null } 37 } 38 } 39 40 $selection = $available | Out-GridView -Title \u0026#34;Select a subscription. Found: $($SubscriptionList.count)\u0026#34; -OutputMode Single 41 42 try { 43 if (-not $selection) { 44 Write-Host -ForegroundColor Red \u0026#34;No subscription selected. Operation cancelled.\u0026#34; 45 return 46 } 47 48 Write-Host -ForegroundColor Cyan \u0026#39;Switching to:\u0026#39;, $selection.Subscription 49 Set-AzContext -SubscriptionId $selection.SubscriptionId | Out-Null 50 Get-AzContext 51 } catch { 52 Write-Host -ForegroundColor Red \u0026#34;Invalid input, please enter a valid index!\u0026#34; 53 } 54} 55 56Clear-Host 57Switch-AzContext Here is the script output:\nEnjoy!\n","link":"https://benoit-gaumard.io/blog/post/12--azure-subscription-switcher/","section":"post","tags":["productivity","tools","powershell"],"title":"Azure subscription switcher"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/diagrams/","section":"tags","tags":null,"title":"Diagrams"},{"body":"If you want an integrated solution and avoid multiple external tools (like Visio, PowerPoint, etc.) to create diagrams, here is a very helpful extension.\nThis unofficial extension integrates Draw.io (also known as diagrams.net) into VS Code.\nTo create a new diagram, just create an empty *.drawio, *.drawio.svg, or *.drawio.png file and open it.\n.drawio.svg files are valid .svg files that can be embedded in GitHub readme files! No export needed. .drawio.png files are valid .png files! No export needed. You should use .svg whenever possible. It's very practical when you make updates without re-importing everything. Just make the change and that’s all.\nDownload is available here: Draw.io Integration – Visual Studio Marketplace\nHere is the demo: ","link":"https://benoit-gaumard.io/blog/post/6-draw.io-vscode-extension-a-must-have-for-your-diagrams/","section":"post","tags":["productivity","tools","diagrams"],"title":"Draw.io VSCode Extension: A Must-Have for Your Diagrams"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/tools/","section":"tags","tags":null,"title":"Tools"},{"body":"","link":"https://benoit-gaumard.io/blog/categories/tools/","section":"categories","tags":null,"title":"Tools"},{"body":"Free dashboards that provides a visualization of cyber attacks all over the world.\nThe main security players offer free dashboards that provide a simple and comprehensive visualization to better understand the dangers of the Internet and help companies analyze the state of various threats.\nSome interesting sites to bookmark:\nSonicwall: https://securitycenter.sonicwall.com/m/page/worldwide-attacks Netscout: https://horizon.netscout.com/?mapPosition=0.00~0.00~1.00 Talos: https://talosintelligence.com/fullpage_maps/pulse Digital attack map: https://www.digitalattackmap.com/#anim=1\u0026color=0\u0026country=ALL\u0026list=0\u0026time=18763\u0026view=map Checkpoint: https://threatmap.checkpoint.com/ Fortinet: https://threatmap.fortiguard.com/ https://threatbutt.com/map/ ","link":"https://benoit-gaumard.io/blog/post/14-cyber-attacks-live-maps/","section":"post","tags":["Security"],"title":"Cyber attacks live maps"},{"body":"Here is the step by step guide to host your Hugo website on Github Pages.\nPrerequisites Before diving in, ensure you have the following:\nGit A GitHub account Hugo installed on your system and running localy Note In this article we will copy a local Hugo web site to Git Hub Pages. First ensure your web site is working well locally. For more information on creating your first Hugo website locally, check out this guide.\nSetting Up GitHub Pages GitHub Pages is a free static site hosting service that takes HTML, CSS, and JavaScript files straight from a repository on GitHub, optionally runs the files through a build process, and publishes a website.\nFollow these steps to get started:\nCreate a new repository named username.github.io to publish your user site. eg. Benoit-Gaumard.github.io\nEnable GitHub Pages in your repository settings from Setting --\u0026gt; Pages When enabled a new deployment actions pipeline \u0026quot;pages build and deployment\u0026quot; with be automatically created.\nClone the repository to your local machine.\n1git clone https://github.com/Benoit-Gaumard/Benoit-Gaumard.github.io.git Add an index.html file to your repository. 1\u0026lt;h1\u0026gt; Demo site on Git Hub pages\u0026lt;/h1\u0026gt; Commit and push your changes 1cd Benoit-Gaumard.github.io 2git add . \u0026amp;\u0026amp; git commit -m \u0026#39;publish first github pages website\u0026#39; -a \u0026amp;\u0026amp; git push The deployment will start after the push\nWithin a few moments, your web page be live at https://username.github.io. eg. https://Benoit-Gaumard.github.io\nCreate the deployment pipeline Create an empty yaml file in your local repository. 1.github/workflows/hugo.yaml Copy and paste the YAML below into the file you created. Change the branch name and Hugo version as needed.\n1code Copy your local web site to GitHub Pages 1$SourcePath = \u0026#34;C:\\REPOS\\BLOG\\hugo-website\\bga-new-site\u0026#34; 2$DestinationPath = \u0026#34;C:\\REPOS\\BLOG\\Benoit-Gaumard.github.io\u0026#34; 3 4# Delete existing folder content 5Get-ChildItem -Path $DestinationPath -Exclude \u0026#34;.git\u0026#34;, \u0026#34;.github\u0026#34; | 6 ForEach-Object { 7 if ($_.PSIsContainer) { 8 Remove-Item -Path $_.FullName -Recurse -Force 9 } else { 10 Remove-Item -Path $_.FullName -Force 11 } 12 } 13 14# Get all items in the source path, excluding .git and .gity 15Get-ChildItem -Path $SourcePath -Recurse -Exclude \u0026#34;.git\u0026#34;, \u0026#34;.github\u0026#34; | 16 ForEach-Object { 17 # Adjust the destination path for each item 18 $targetPath = $_.FullName -replace [regex]::Escape($SourcePath), $DestinationPath 19 20 # Ensure that the destination directory exists 21 if ($_.PSIsContainer) { 22 # Create directory if it\u0026#39;s a folder 23 if (!(Test-Path -Path $targetPath)) { 24 New-Item -ItemType Directory -Path $targetPath -Force 25 } 26 } else { 27 # Copy files 28 Copy-Item -Path $_.FullName -Destination $targetPath -Force 29 } 30 } 31 32# Commit and deploy 33cd C:\\REPOS\\BLOG\\Benoit-Gaumard.github.io 34git add . \u0026amp;\u0026amp; git commit -m \u0026#39;publish new content\u0026#39; -a \u0026amp;\u0026amp; git push The deployment starts\nYou new hugo website is up and runnning at https://username.github.io. eg. https://Benoit-Gaumard.github.io\n","link":"https://benoit-gaumard.io/blog/post/16-how-to-host-your-hugo-website-on-github-pages/","section":"post","tags":["hugo","github"],"title":"How to host your Hugo website on Github Pages?"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/hugo/","section":"tags","tags":null,"title":"Hugo"},{"body":"","link":"https://benoit-gaumard.io/blog/categories/hugo/","section":"categories","tags":null,"title":"Hugo"},{"body":"This section offers a curated collection of helpful links, providing resources and tools to enhance your understanding and make your experience more productive.\n👀 New Links To Check Back To Top\nAzure Talk Blog: https://blog.zuehlke.cloud/ 🏗️ Architecture Back To Top\nFree Ebooks and whitepapers Azure services limits: https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits ⭐ Cloud Adoption Framework CAF🔥 Well Architected Framework WAF🔥 https://social.technet.microsoft.com/wiki/contents/articles/630.microsoft-azure-survival-guide.aspx https://social.technet.microsoft.com/wiki/contents/articles/33800.azure-iaas-v2-arm-design-series-azure-subscriptions.aspx Azure offers details: https://azure.microsoft.com/en-us/support/legal/offer-details/ ⭐ https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/decision-guides/subscriptions/ https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles Azure Reference Architectures 🔥 Cloud adoption antipatterns Azure supported workloads: https://docs.microsoft.com/en-US/troubleshoot/azure/virtual-machines/server-software-support Microsoft Assessments and review : https://docs.microsoft.com/en-us/assessments/?mode=home 🔥 Docs Update Tracker: https://docsupdatetracker.net/ ⭐⭐⭐ Landing Zone mission-critical: https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/containers/aks-mission-critical/mission-critical-landing-zone Azure Quick Review: https://github.com/Azure/azqr Azure Sandbox: https://learn.microsoft.com/en-us/azure/architecture/guide/azure-sandbox/azure-sandbox Azure Dev Center: https://github.com/Azure-Samples/DevCenter CAF Additionnal resources: https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-setup-guide/staying-current?tabs=AdditionalResources#tabpanel_1_AdditionalResources Cloud Adoption Framework Tools and Templates: https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/resources/tools-templates MOAW: https://microsoft.github.io/moaw/ 🔥 Azure Landing Zone catalog: https://github.com/oliverlabs/alz-catalogue https://azureanimations.github.io/ ⭐⭐⭐ 🅰 ARM Back To Top\nAzure Quickstart Templates ARMViz Azure resource explorer Rest API Browser ⭐⭐⭐ 👀 Analytics and monitoring Back To Top\nLog Analytics Query Portal: https://portal.loganalytics.io/demo#/query/main Kusto explorer: https://docs.microsoft.com/en-us/azure/data-explorer/kusto/tools/kusto-explorer Monitoring Azure by using Grafana dashboards: https://devblogs.microsoft.com/devops/monitoring-azure-by-using-grafana-dashboards/ Azure Monitor Community: https://github.com/microsoft/AzureMonitorCommunity🔥 Log Analytics cost: https://trstringer.com/log-analytics-expensive-part-1-discovery/ azure-monitoring-certificates: https://blog.smartcloudarchitect.fr/azure-monitoring-certificates Azure Monitor Logs table reference: https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/tables-category AMBA: https://techcommunity.microsoft.com/t5/azure-governance-and-management/azure-monitor-baseline-alerts-amba-for-azure-landing-zone-alz-is/ba-p/3936951 🟦 Entra Id (Azure Active Directory) Back To Top\nTenant availability check 1: https://account.azure.com/organization Tenant availability check 2: https://o365.rocks/ https://gettenantpartitionweb.azurewebsites.net/ Interactive authentication: https://microsoft.com/devicelogin/ Azure Active Directory admin center: http://aad.portal.azure.com/🔥 Azure AD Exporter: https://github.com/microsoft/azureadexporter/ Azure AD Big Picture: https://raw.githubusercontent.com/msandbu/azuread/main/AzureAD%20Big%20picture.jpg🔥 Microsoft Graph Changelog: https://developer.microsoft.com/en-us/graph/changelog/?search= Azure AD Security Config Analyzer (AADSCA): https://github.com/Cloud-Architekt/AzureAD-Attack-Defense/blob/main/AADSecurityConfigAnalyzer.md Azure-AccessPermissions: https://github.com/csandker/Azure-AccessPermissions Decode, verify and generate Token: https://jwt.io/ AAD Osint tool: https://aadinternals.com/osint/ 🔥 https://myaccount.microsoft.com/groups/groups-i-belong-to https://cyberchef.org/ (Decode JWT tokens and more) 🔥 https://graphpermissions.merill.net/permission/ 🔥🔥🔥 💪 Bicep Back To Top\nBicep from 0 to hero: https://github.com/rchaganti/bicepbookexamples Convert ARM to Bicep online: https://bicep.kwitantie.app/ Bicep playground: https://azure.github.io/bicep/ 🏅 Certifications Back To Top\nOfficial certifications training poster: https://aka.ms/TrainCertPoster Browse Certifications by roles: https://learn.microsoft.com/en-us/certifications/ Microsoft Learn: https://docs.microsoft.com/en-us/learn/ Exam Sandbox, demo the Microsoft exam experience: https://aka.ms/examdemo Microsoft learn community: https://techcommunity.microsoft.com/t5/microsoft-learn/ct-p/MicrosoftLearn Practice Assessments for Microsoft Certifications: https://learn.microsoft.com/en-us/certifications/practice-assessments-for-microsoft-certifications Practice Assessments for Microsoft Certifications 2: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/prep-for-certification-exams-with-free-practice-assessments-on/ba-p/3666866 Azure Open Source Labs: https://learn.microsoft.com/en-us/samples/azure-samples/azure-opensource-labs/azure-opensource-labs/ ⛅ Cloud Services Comparison Back To Top\nPublic Cloud Services Comparison: https://comparecloud.in/ Azure VM Comparison: https://azureprice.net/ Compare AWS and Azure services to Google Cloud https://cloud.google.com/free/docs/aws-azure-gcp-service-comparison?utm_source=google\u0026amp;utm_medium=blog\u0026amp;utm_campaign=FY21-Q2-Product-Mapping-Blog\u0026amp;utm_content=documentation https://docs.microsoft.com/en-us/azure/architecture/aws-professional/services Compare Azure and AWS services Azure MarketPlace: https://azuremarketplace.microsoft.com/en-us/ 🚨 Compliance Back To Top\nMicrosoft compliance offerings: https://docs.microsoft.com/en-us/compliance/regulatory/offering-home?view=o365-worldwide Microsoft Privacy Statement: https://privacy.microsoft.com/en-us/privacystatement Microsoft trust center: https://www.microsoft.com/en-us/trust-center Service trust portal: https://servicetrust.microsoft.com/ Compliance Manager portal: https://servicetrust.microsoft.com/ComplianceManager/V3# 📊 DNS Back To Top\nPrivate DNS Resolver: https://blog.teknews.cloud/network/2024/10/27/Back_tobasics_About_Private_DNS_Resolver.html 📚 Data Back To Top\nAzure Data Explorer https://dataexplorer.azure.com/ 📈 DashBoards Back To Top\nAzure Orphan Resources workbook: https://techcommunity.microsoft.com/t5/fasttrack-for-azure/azure-orphan-resources/ba-p/3492198 Network Security Dashboard for Microsoft Defender for Cloud: https://github.com/Azure/Microsoft-Defender-for-Cloud/tree/main/Workbooks/Network%20Security%20Dashboard CCO GitHub Contributions Dashboard: https://github.com/Azure/CCOInsights#cco-github-contributions-dashboard🔥 CCO ADO Contributions Dashboard: https://github.com/Azure/CCOInsights#cco-ado-contributions-dashboard Azure Hybrid Benefit Workbook: https://github.com/arthurclares/AzureHybridBenefitWorkbook AKS Security Workbook: https://techcommunity.microsoft.com/t5/microsoft-sentinel-blog/new-azure-kubernetes-service-aks-security-workbook/ba-p/1867134 Azure Hybrid Benefits Workbook: https://techcommunity.microsoft.com/t5/healthcare-and-life-sciences/tracking-azure-hybrid-benefit-using-azure-workbooks/ba-p/3798857 Azure Saving Plans Dashboard: https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/azure-savings-dashboard/ba-p/3816131 Azure Cost Management Dashboard: https://github.com/sairashaik6677/azure-costmanagement-dashboard Cloud Roles and Operations Management DashBoard: https://github.com/Azure/cloud-rolesandops Azure Service Retirement Workbook: https://learn.microsoft.com/en-us/azure/advisor/advisor-how-to-plan-migration-workloads-service-retirement Azure Inventory Workbook: https://github.com/scautomation/Azure-Inventory-Workbook 🔥 https://github.com/4R9UN/Cloud-Events/tree/main 🚀 DevOps Back To Top\nLearn git branching: https://learngitbranching.js.org/ 🔥 Azure DevOps Labs: https://azuredevopslabs.com/ Azure DevOps Demo Generator: https://azuredevopsdemogenerator.azurewebsites.net/ Azure DevOps Organization: https://aex.dev.azure.com/🔥 Devops Resources: https://github.com/bregman-arie/devops-resources Devops Bookmark: https://www.devopsbookmarks.org/ Devops roadmap: https://roadmap.sh/ The Microsoft Azure Developer's Cheat Sheet: https://github.com/milanm/azure-cheat-sheet awesome-french-devops: https://github.com/stephrobert/awesome-french-devops/ Secret scanning in Azure DevOps: https://johnlokerse.dev/2023/05/24/secret-scanning-in-azure-devops-with-defender-for-devops/ CNCF Cloud Native Interactive Landscape: https://landscape.cncf.io/ https://www.conventionalcommits.org/ devsecops-periodic-table: https://digital.ai/learn/devsecops-periodic-table/ Continuous Delivery Landscape: https://landscape.cd.foundation/ DevOps Anti-Types: https://web.devopstopologies.com/#anti-types https://rios.engineer/🔥 https://explainshell.com/ 🚀 DevOps News Back To Top\nLe journalduhacker Human Coders News Dev.to 📅 Events Back To Top\nDevelopers Events 🔥 💵 FinOps Back To Top\nTotal Cost of Ownership (TCO) Calculator Azure Pricing calculator 🔥 Strategies to realizing Cost Savings in Azure Budget Alert in Teams Azure Optimization Engine (AOE) Microsoft Defender for Cloud Price Estimation Dashboard Cost optimization pillar Azure Cost Reporting PBI Project Bose: Cost of an Enterprise by cost centers, divisions, projects The Azure FinOps guide 🔥 Azure Cost Cli 🔥 FinOps whitepaper What causes Azure costs to increase https://github.com/microsoft/finops-toolkit/releases/tag/v0.1.1 Optimize Your Azure Costs 🔥 https://microsoft.github.io/finops-toolkit/ Apply AHB at Scale https://rios.engineer/get-azure-cost-estimates-in-azure-devops-pr-comments-with-bicep/ 🤣 Fun Back To Top\nGoodtechthings.com geekprank Doom Web: https://www.emaxilde.net/assets/games/doom/doom.html 🐙 GitHub Back To Top\nGitHub emoji cheat sheet 🔥 Build your own octocat Bitmoji All IP ranges used by GitHub Actions runners OIDC : https://techwatching.dev/posts/scripting-azure-ready-github-repository 🏛️ Governance Back To Top\nFind resource providers by Azure services - Azure Resource Manager | Microsoft Learn 🔥 Azure Policy Aliases (mats.codes) AzAdvertizer 🔥 AzGovViz Continuous Cloud Optimization (CCO) 🔥 AzureSecurityCenterInventory Azure Resource Inventory (ARI) Azure Visualizer (AzViz) New (diagrams.net) diagram Azure Raci toolkit Azure Naming Tool Azure Periodic Table of Resource Naming Convention 🔥 Naming convention initiative: https://github.com/matthiasguentert/azure-naming-convention-initiative 🔥 The perfect Azure naming convention remove Unauthorized Role Assignments Azure Analytics Architecture Advisor 🔍 Graph KQL Back To Top\nKQL - threat hunting hub https://kql-search-2.vercel.app/ https://www.kqlsearch.com/ https://techcommunity.microsoft.com/t5/azure-governance-and-management/announcing-authorizationresources-in-azure-resource-graph/ba-p/3813912?WT.mc_id=DT-MVP-5001664 Microsoft Kusto Detective Agency Contest Query collection: https://github.com/globalbao/azure-resource-graph https://github.com/tyconsulting/AzureResourceGraph/tree/master/Queries 🔍 Graph https://developer.microsoft.com/en-us/graph/graph-explorer 💥 HA and DR Back To Top\nAzure Geographies and regions Azure cross regions replication Azure regions and availability zones Azure Business Continuity Guide Resilience in Azure Reliability with microsoft Azure Infographic https://github.com/ElanShudnow/AzureCode/tree/main/PowerShell/VMRegionZonalAvailability 📢 Informations Back To Top\nAzure Updates 🔥 Azure Info Hub Azure Weekly AzureFeeds Microsoft Blogs by products https://bonjourlafuite.eu.org/ https://azurefeeds.bmeurl.co/123F59FB 🔥🔥🔥 🔍 LightHouse Back To Top\nSecuring Azure Lighthouse with Azure Policy and PIM 🔍 Licensing Back To Top\nhttps://m365maps.com/ 🔥 https://m365insights.org/ 🔥 📌 Mind Maps Back To Top\nhttps://squasta.github.io/ 📌 Misc Back To Top\nAzure Mask https://chromewebstore.google.com/detail/az-mask/amobeamdmdnloajcaiomgegpakjdiacm?hl=en-US Raspberry Simulator for IOT Hub sqlflow Nuage de mots Wiki Tech Azure Tips and Tricks Code Error quickref cheatsheets and quick references https://login.microsoftonline.com/logout.srf https://login.microsoftonline.com/login.srf https://cheatography.com/ Azure serverless community library Microsoft MVP's Map : https://mvpsglobe.web.app/ https://www.bullshitor.com/ https://www.emaxilde.net/assets/games/doom/doom.html GUID generator: https://guidgenerator.com/ https://quoootes.com/ https://miniwebtool.com/random-quote-generator/ https://quozio.com/ https://varnz.ai/ai-quote-generator ⏩ Move or migration Back To Top\nhttps://github.com/ElanShudnow/AzureCode/tree/main/PowerShell/AzResourceMoveSupport https://github.com/mustafakaya/Azure-Reliability-Checker-Tool Migration Execution Guide 🌐 Network Back To Top\nhttps://azureipranges.azurewebsites.net/ 🔥\nhttps://techcommunity.microsoft.com/t5/azure-networking-blog/the-azure-networking-map/ba-p/3706001\nNetwork-segmentation-cheat-sheet\nhttps://github.com/Azure/Azure-Network-Security\nhttps://github.com/nehalineogi/azure-networking\nhttps://github.com/Azure/ipam\nhttps://www.submarinecablemap.com/\nhttps://github.com/ElanShudnow/AzureCode/tree/main/PowerShell/AzVNETOverlap\nhttps://github.com/mattfeltonma/azure-network-journey\nhttps://learn.microsoft.com/en-us/azure/architecture/example-scenario/gateway/firewall-application-gateway\nhttps://learn.microsoft.com/en-us/answers/questions/774683/using-azure-firewall-with-web-application-behind-w\nhttps://blog.cellenza.com/cloud-2/comment-deployer-une-architecture-hub-and-spoke-avec-azure-firewall/ 🔥\nhttps://github.com/nicolgit/azure-firewall-mon 🔥\nhttps://techcommunity.microsoft.com/t5/core-infrastructure-and-security/quick-start-guide-to-azure-private-endpoints-with-aks-amp/ba-p/3943803\nhttps://techcommunity.microsoft.com/t5/azure-networking-blog/understanding-expressroute-private-peering-to-address/ba-p/4081850\nAzure IP ranges\nhttps://visualsubnetcalc.com/#\nhttps://azureipranges.azurewebsites.net/\nIPAM: https://github.com/netbox-community/netbox\nhttps://blog.cloudtrooper.net/\nhttps://trippy.rs/ (Network Diag Tool)\nhttps://blog.cloudtrooper.net/2025/01/22/private-link-reality-bites-your-routes-could-be-lying/\nhttps://github.com/1tayH/noisy (Generates random HTTP/DNS traffic noise in the background)\nhttps://az-mdv.az.vupti.me/ Azure Migrate Network Flows Analysis 🔥🔥🔥\nhttps://blog.nillsf.com/index.php/2018/11/06/azure-paas-services-connected-to-your-vnet/ VNET Injection vs Service Endpoints\nhttps://github.com/jokob-sk/NetAlertX\nAzure function VNet integration: https://dearsi-mocha.github.io/cloudsauce/2020/04/23/azure-function-vnet/ 🔥\nInspector Gadget : https://github.com/jelledruyts/InspectorGadget 🔥\nAzure function VNet integration: https://dev.to/rokicool/azure-function-app-flex-conumption-in-private-vnet-via-iac-1j62\nWeb app private link with Azure SQL DB and storage: https://learn.microsoft.com/en-us/samples/azure/azure-quickstart-templates/web-app-regional-vnet-private-endpoint-sql-storage/\nAuthenticating Azure Function App: https://medium.com/@sumindaniro/azure-function-app-as-the-backend-api-for-webapps-reactjs-c6a6ce26246\n👮 Policies Back To Top\nhttps://github.com/Azure/enterprise-azure-policy-as-code Azure Policy As Code https://medium.com/microsoftazure/devsecops-policy-as-code-with-azure-pipelines-86cc1e27f03c Policy-as-code with Azure Pipelines https://techcommunity.microsoft.com/t5/microsoft-defender-for-cloud/policy-distribution-dashboard-for-microsoft-defender-for-cloud/ba-p/3264712 Policy Distribution Dashboard for Microsoft Defender for Cloud https://github.com/rjygraham/AzurePolicy/tree/main/Samples Ryan Graham GitHub Repo https://github.com/tyconsulting/azurepolicy tyconsulting GitHub Repo https://github.com/Azure/Community-Policy\" Azure Community Policy GitHub Repo🔥 https://www.cloudsma.com/2021/10/build-azure-policy-compliance-workbook/ Azure Policy Compliance WorkBook https://github.com/globalbao/awesome-azure-policy\"\u003eAWESOME-Azure-Policy https://github.com/JimGBritt/AzurePolicy/tree/master/AzureMonitor/Scripts Azure Diagnostics Policy Generator Configure\"\u003ehttps://www.cloudpartner.fi/?p=7015\"\u003eConfigure centralized policy management https://policyalias.mats.codes/ Policies Aliases List 🔥 https://purple.telstra.com/blog/azure-policy-as-code-with-terraform-part-1 Terraform policies as code 🔥 https://github.com/globalbao/azure-policy-as-code/tree/mainTerraform policies as code repo🔥 https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/scenarios/cloud-scale-analytics/eslz-policies CAF Policies 🔥 https://blog.tyang.org/2023/09/30/natively0monitoring-azure-policy-compliance-states-in-azure-monitor-2023-edition/ https://andrewmatveychuk.com/how-to-validate-azure-tags/ https://medium.com/@geralexgr/azure-policy-require-specific-tags-on-resources-72b911f6c725 https://www.blueboxes.co.uk/working-with-tags-in-azure-resource-graph-explorer https://github.com/fawohlsc/azure-policy-testing https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/azure-policy-recommended-practices/ba-p/3798024?WT.mc_id=DT-MVP-5001664 https://azure.github.io/enterprise-azure-policy-as-code https://github.com/Azure/enterprise-azure-policy-as-code https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/azure-enterprise-policy-as-code-a-new-approach/ba-p/3607843 https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/infrastructure-as-code-testing-with-azure-policy/ba-p/3921765?WT.mc_id=DT-MVP-5001664 https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/cost-governance-with-azure-policy/ba-p/3791888?WT.mc_id=DT-MVP-5001664 https://techcommunity.microsoft.com/t5/azure-network-security-blog/enforcing-and-managing-azure-ddos-protection-with-azure-policy/ba-p/3933172?WT.mc_id=DT-MVP-5001664 https://techcommunity.microsoft.com/t5/fasttrack-for-azure/azure-policy-for-azure-container-apps-yes-please/ba-p/3775200?WT.mc_id=DT-MVP-5001664 https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/infrastructure-as-code-testing-with-azure-policy/ba-p/3921765 https://jeffbrown.tech/azure-policy-resource-lock/ https://techcommunity.microsoft.com/blog/azureinfrastructureblog/deny-inbound-nsg-rule-creation-via-azure-policy/4241803 🌐 Portals Back To Top\nAzure Preview portal Azure RC portal Microsoft portals Microsoft portals 2 Azure portals 3 Microsoft Administrator Portals MyApps Azure Cloud Shell Web 🅿 Powershell Back To Top\nIterate over a hashtable in PowerShell Gain insights into your Azure role assignments on subscription level https://github.com/ElanShudnow/AzureCode/tree/main/PowerShell 🧱 Routing and NVA Back To Top\nAzure NVA Redundancy Part I Hub-Spoke Architecture 🔥🔥 Connect Azure with On-Prem Network Part 1 🔥🔥 Enabling Direct On-Prem Site Access to Azure Private VMSS Resources via Internal Load Balancer 💻 Remote Desktop and AVD Back To Top\nhttps://client.wvd.microsoft.com/arm/webclient/index.html https://rdweb.wvd.microsoft.com/ 📝 Services Back To Top\nAzure Charts 🔥 Azure Periodic table Azure Services io Azure Deprecation DashBoard Azure Charts Deprecations 🔥 Azure Charts Arrivals 🔥 Azure Status 🔥 New Azure Status 🔥 Azure Infrastructure Map 🔥 Azure Speed Test 2.0 AzSpeedTest Powershell AzureSpeed SLA for Azure services SLA Calculator https://downdetector.fr/ ✍ Stencils and icons Back To Top\nOfficial Microsoft Azure Cloud and AI Symbol / Icon Set - SVG - Pointer sandroasp Icon Set David-Summers Icon Set 🔥 Azure Docs collection Azure Icons collection 🔥 Azure Patterns collection Azure cds Collection ContentCollateral Azure Icons Libraries for Diagrams.net (Draw.io) 🔥 Azure architecture SVG icons 🔥 Diagram as code Azure Design Studio Azure glyphs and icons Draw.io Azure infrastructure diagrams https://www.svgrepo.com/ https://az-icons.com/ 🪴 Sustainability Back To Top\nMicrosoft Emissions Impact Dashboard 🧑‍🚒 Support Back To Top\nAzure Support plans Azure community support Azure feedback 🔥 🔖 Tags Back To Top\nTag support for Azure resources 🔥 Taggable resources 🔥 Develop your naming and tagging strategy for Azure resources Naming and tagging conventions tracking template How to tag your resources on AWS / GCP / Azure 🟪 Terraform Back To Top\naztfy Azure terraform-azurerm-caf-enterprise-scale Azure caf-terraform-landingzones Terraform from 0 to hero flaviusdinu azure-network-terraform Infracost Johan Vanneuville Terraform and Azure DevOps pipelines Terraform labs How to run PowerShell scripts on Azure VMs with Terraform https://azure.github.io/Azure-Verified-Modules/ https://github.com/tenable/terrascan Azure Federated Identity Guide https://waynegoosen.com/post/azure-federated-identity-credentials-terraform-github-actions-guide/ 🔥 🛫 Terraform Deployment Back To Top\nDeploying terraform-azure-vnet-hub-spoke Deploying azurefirewall-hub-spoke-demo Deploying deploying-and-configuring-azure-firewall-using-terraform Firewall As Code 🔥 https://github.com/DonKoning/megaLinter/tree/main https://github.com/WinOpsDBA/DBAinTheCloud/tree/master/06-vm-extensions https://github.com/nicolgit/hub-and-spoke-playground 💻 Virtual machines Back To Top\nAzure VM sizes Start / Stop VMs 1 Start / Stop VMs 2 Azureprice 🔥 Azure VM Pricing Comparison (2024) (turbo360.com) 🔥 Virtual machines selector 🔥 Automanage Machine Configuration ↗ Virtual Machines Scale Set Back To Top\nvmssdashboard asciivmssdashboard 🌍 Web Back To Top\nWhirl CSS jsoncrack CSS Tree exemple 🎥 Youtube Back To Top\nThéorie en 10mn - Interconnexion de Microsoft Azure avec le monde extérieur 📒 Wiki JS Back To Top\n100% Automated Wiki Deployment with Terraform 100% Managed Wiki Deployment Emoji Cheat Sheet 📸 Photos Back To Top\nDronestock Pexels Pixabay ","link":"https://benoit-gaumard.io/blog/page/blogroll/","section":"page","tags":null,"title":"Blog Roll"},{"body":"This section offers a curated collection of helpful links, providing resources and tools to enhance your understanding and make your experience more productive.\nBlogRoll AI 🧠 AI Back To Top\nInteractive collection of the 18 Guidelines for Human-AI Interaction ","link":"https://benoit-gaumard.io/blog/page/blogroll-ai/","section":"page","tags":null,"title":"Blog Roll Security"},{"body":"This section offers a curated collection of helpful links, providing resources and tools to enhance your understanding and make your experience more productive.\n👮 Scanner Back To Top\nWeb application security scanner : https://www.arachni-scanner.com Informations et recherches sur la sécurité : https://www.w4rri0r.com Powershell Empire : https://www.powershellempire.com/ Security checks : https://www.malwarearchaeology.com/cheat-sheets/ Identifying \u0026amp; Exploiting Leaked Azure Storage Keys : https://www.notsosecure.com/identifying-exploiting-leaked-azure-storage-keys/ MFA demo: https://woodgroveemployee.azurewebsites.net/landing Open Source vulnerability scanner : https://github.com/projectdiscovery/nuclei 👮 CVEs Back To Top\nTrack and Monitor CVEs in Real-Time: https://huntdb.com/ 💀 Security Back To Top\nMicrosoft Cybersecurity Reference Architectures (MCRA) 🔥 Azucar ScoutSuite Secure DevOps Kit Skyark MicroBurst Stormspotter Cloud Katana Azure Security Control Mappings to MITRE ATT\u0026amp;CK® Azure Hunter Microsoft Security Response Center (MSRC) Azure Review CheckList 🔥 CloudSploit Security Remediation Guides Identifying \u0026amp; Exploiting Leaked Azure Storage Keys cloud security vulnerabilities Windows AppLocker Bypass: regsvr32.exe /s /u /i:test.sct scrobj.dll Cybersecurity-jobs-skills-workshop HackTricks Azure Secret Rotation Depix is a tool for recovering passwords from pixelized screenshots Snoop Get Azure bearer token Arachni Web application security scanner OSINT web-check Hack The Box Root Me GraphRunner Open bucket and storage account Labyrinthinesecurity silhouette https://web-check.xyz/ EDR telemetry https://www.edr-telemetry.com/ https://github.com/intuitem/ciso-assistant-community https://web-check.as93.net/ https://maester.dev/ ","link":"https://benoit-gaumard.io/blog/page/blogroll-security/","section":"page","tags":null,"title":"Blog Roll Security"},{"body":"In this section, you’ll discover the most recent updates and insights about Azure gathered from a diverse range of websites, ensuring you stay informed about the latest trends, news, and developments about Azure.\nInfo 3 latest posts from various blogs. Feeds are updated automaticaly every day.\n🆕 Azure Feeds Blog Thu, 13 Aug 2026: Opening Up Sponsorship on My Blog\nThu, 13 Aug 2026: Using Azure AI Foundry resource for .NET Azure.AI.TextAnalytics and Azure.AI.Translation.Text Clients\nThu, 13 Aug 2026: Deploy Azure Monitor SLI Alerting as Code\n🆕 Azure Governance and Management Blog Tue, 28 Jul 2026: Introducing Compliance Substate for Azure Policy Exemptions!\nThu, 23 Jul 2026: Introducing Kubernetes-Native Policy Validation with CEL and VAP in Azure Policy\nTue, 28 Jul 2026: Azure landing zone (ALZ) enters its next chapter\n🆕 Azure Infrastructure Blog Thu, 13 Aug 2026: From Silicon to Systems: Bending the Cost and Complexity Curves of AI\nFri, 31 Jul 2026: Move a live GitLab project between groups without breaking Terraform state or CI/CD\nThu, 16 Jul 2026: Azure Cobalt: Workload-Aware Power Management for More Efficient Datacenters\n🆕 Azure Architecture Blog Thu, 30 Jul 2026: Skill or Sub-Agent. Choosing AI Capabilities You Will Actually Reuse\nWed, 29 Jul 2026: Mastering GitHub Copilot Budgets: How to Prevent Surprise Overages Without Blocking Devs\nTue, 28 Jul 2026: Token Economics in Practice\n🆕 Azure Networking Blog Thu, 11 Jun 2026: DoH is now generally available on Windows DNS Server\nWed, 17 Jun 2026: Announcing Windows CLAT Public Preview\nTue, 10 Feb 2026: Secure DNS with DoH: Public Preview for Windows DNS Server\n🆕 Azure Network Security Blog Mon, 13 Jul 2026: Secure Native Access to Azure Kubernetes Service (AKS) Private Clusters with Azure Bastion\nThu, 11 Jun 2026: A deep dive into Azure Bastion session recording\nWed, 17 Jun 2026: Designing Cloud Landing Zones by Traffic Flow: A Defence‑in‑Depth, DMZ‑First Architecture\n🆕 Azure Storage Blog Tue, 11 Aug 2026: Accelerate Inference on AKS with Azure Blob Storage and NVIDIA Dynamo\nThu, 09 Jul 2026: Optimize Oracle workloads on Azure with Azure NetApp Files\nMon, 29 Jun 2026: Announcing General Availability of Client-Side Data Integrity Protections in Azure Blob Storage\n🆕 Azure Tools Blog Thu, 30 Jul 2026: Terraform AzureRM provider 5.0 now generally available\nSun, 07 Jun 2026: Faster az login: introducing --skip-subscription-discovery and targeted --subscription\nTue, 12 May 2026: From Prompt to Production: Open in VS Code for Terraform in Azure Copilot\n🆕 Azure FinOps Blog Thu, 30 Jul 2026: Reservation exchanges for Azure services covered by savings plans end starting Feb. 1, 2027\nThu, 30 Jul 2026: Introducing Cost Management and Pricing Toolsets in Azure Resource Manager MCP Server\nTue, 28 Jul 2026: Cap it with GitHub, make it count with Azure: governing GitHub Copilot spend\n🆕 Core Infrastructure and Security Blog Mon, 03 Aug 2026: Check This Out! (CTO!) Guide (August 2026)\nFri, 31 Jul 2026: Securing Enterprise AI Agents with Microsoft Sentinel\nMon, 27 Jul 2026: Device Code Flow: The Gift That Keeps on Giving — To Attackers\n🆕 Startups at Microsoft Blog Sat, 01 Aug 2026: From reactive firefighting to proactive operations: custom skills for Azure SRE Agent\nSat, 01 Aug 2026: Azure AI Foundry: from zero to production\nWed, 29 Jul 2026: Your startup doesn\u0026#39;t have an SRE team. Now what?\n🆕 Entra Blog Mon, 10 Aug 2026: What\u0026#39;s New in Microsoft Entra: August 2026\nMon, 10 Aug 2026: Microsoft Entra Tenant Governance is now generally available\nWed, 05 Aug 2026: End VPN gaps with identity-first access\n","link":"https://benoit-gaumard.io/blog/page/latest-news/","section":"page","tags":null,"title":"Latest Azure news"},{"body":"","link":"https://benoit-gaumard.io/blog/page/","section":"page","tags":null,"title":"Pages"},{"body":"This article explains how to create your first web site on Windows using Hugo.\nPrequisites Install Chocolatey (Chocolatey is a free and open-source package manager for Windows) Install Git https://git-scm.com/book/en/v2/Getting-Started-Installing-Git Install Hugo From a terminal type:\n1choco install hugo-extended Create a new hugo web site 1hugo new site \u0026#34;mysite\u0026#34; Go to the previously created web site\n1cd mysite 1git init Install a theme (eg. Hugo Clarity Theme) 1git submodule add https://github.com/chipzoller/hugo-clarity themes/hugo-clarity For hugo clarity copy current config and pages 1Copy-Item -Path \u0026#34;themes/hugo-clarity/exampleSite/*\u0026#34; -Destination \u0026#34;.\u0026#34; -Recurse -Force 2Remove-Item -Path \u0026#34;hugo.toml\u0026#34; -Force Display you website locally 1hugo server You have a demo a local demo of your web site from: http://localhost:1313/\nCreate your first post 1hugo new content content/post/my-first-post.md Add markdown content 1+++ 2title = \u0026#39;My First Post\u0026#39; 3date = 2024-01-14T07:07:07+01:00 4draft = true 5+++ 6 7## Introduction 8 9This is **bold** text, and this is *emphasized* text. 10 11Visit the [Hugo](https://gohugo.io) website! Enjoy!\n","link":"https://benoit-gaumard.io/blog/post/1-create-your-first-hugo-website-locally/","section":"post","tags":["Hugo"],"title":"Create your first Hugo website locally on Windows"},{"body":"Why I migrated from Wordpress to Hugo website. Pros and cons.\nWordPress vs. Hugo: Understanding the Difference and Why Hugo Might Be Right for You Building a website today means choosing between many different tools and platforms. Two popular options—WordPress and Hugo—offer very different approaches to website creation, each with its strengths and ideal use cases. In this post, we’ll dive into the core differences between WordPress and Hugo and explore why Hugo may be the perfect fit for your needs.\nWhat is WordPress? WordPress is a content management system (CMS) that powers over 40% of websites on the internet. It’s known for its user-friendly, visual interface, extensive themes and plugins, and a large community that offers support, customization, and resources. WordPress allows users to create websites without knowing how to code, making it accessible to beginners.\nKey Features of WordPress: Database-Driven: Content, themes, and plugins are stored in a database, allowing users to update content directly through the dashboard. Extensive Plugins: Over 50,000 plugins enable you to add virtually any functionality, from e-commerce features to SEO tools. Themes and Customization: WordPress themes make it easy to achieve different styles without design experience. Community Support: A huge community of developers, designers, and users makes it easy to find resources and support. What is Hugo? Hugo is a static site generator (SSG) known for its speed and simplicity. Instead of relying on a database, Hugo generates HTML files that are ready to be served directly to visitors. It doesn’t come with a visual content management interface like WordPress, but instead, works well for developers and users familiar with Markdown and a code-based workflow.\nKey Features of Hugo: Blazing Fast Speed: Hugo generates static pages quickly, with site builds often taking seconds regardless of the size of the website. Content in Markdown: Content is written in Markdown files, making it easy to organize and version control. No Database Needed: Because there’s no database, sites are secure and efficient, with minimal server requirements. Flexible Theming: Hugo’s themes are powerful and customizable, providing a good range of layouts and styles. Developer-Friendly: It’s ideal for developers who want full control over their site’s structure and performance. WordPress vs. Hugo: Key Differences 1. Content Management WordPress: User-friendly dashboard, easy content editing, and media management make WordPress ideal for non-developers and content-heavy sites. Hugo: Content is written in Markdown and stored as static files, which can be slightly challenging for non-technical users but provides a lightweight, code-driven approach. 2. Speed and Performance WordPress: Database queries, plugins, and a larger codebase can impact performance, especially for high-traffic sites. Hugo: Static HTML files load quickly and efficiently, allowing Hugo sites to handle traffic spikes with minimal load times. 3. Hosting and Scalability WordPress: Typically requires a hosting environment with a server and database. Managed WordPress hosting solutions are available, but costs may increase with traffic. Hugo: Hugo’s static pages can be hosted on platforms like GitHub Pages, Netlify, or any basic web server, which keeps hosting costs low and scalability easy. 4. Security WordPress: The reliance on plugins and a server with a database can expose WordPress sites to security risks if not carefully managed. Hugo: Hugo sites are secure by design, as there’s no backend database or complex server interaction, minimizing vulnerability to attacks. 5. Customization and Flexibility WordPress: Highly customizable with plugins and themes but may require more resources to optimize for performance. Hugo: Flexible for developers, but without a plugin ecosystem. Customizations are done by editing configuration files and theme templates. Advantages of Using Hugo for Your Website For certain types of websites, Hugo offers significant benefits over WordPress:\n1. Unmatched Speed Hugo is incredibly fast. Sites built with Hugo load quickly, and even large sites with thousands of pages can be generated in seconds. This makes Hugo a great choice for SEO and user experience, as search engines and visitors alike prefer fast-loading sites.\n2. Enhanced Security Without a backend database or plugins, Hugo sites are inherently secure. There’s no risk of SQL injection attacks, plugin vulnerabilities, or outdated core software because there’s no dynamic code running on the server.\n3. Low Hosting Costs Hugo sites are static and can be hosted on free or low-cost static hosting services such as GitHub Pages, Netlify, or Vercel. This makes Hugo a budget-friendly choice for individuals or organizations looking to save on hosting expenses.\n4. Version Control for Content Since Hugo stores content in Markdown files, it’s easy to manage and track changes with version control tools like Git. This makes Hugo ideal for collaborative projects, documentation sites, and developers who want precise control over content updates.\n5. Developer-Friendly Customization Hugo’s configuration and templating system offer extensive flexibility, making it easy for developers to build highly customized and optimized sites without relying on third-party plugins. For a technical audience, this level of control can be a significant advantage.\nWhen Should You Choose Hugo? Hugo is an excellent choice if:\nYou want a fast, lightweight, and secure website. You have technical experience or are comfortable learning Markdown and basic web development concepts. Your site doesn’t require a lot of dynamic, user-generated content (like comments or e-commerce). You prefer low hosting costs and an easy deployment process. When Should You Choose WordPress? WordPress is a better fit if:\nYou need a user-friendly CMS for frequent content updates. Your site will rely heavily on plugins for functionality (e.g., e-commerce, social features). You have minimal technical knowledge and prefer a visual editor. You want access to a large community and extensive support resources. Conclusion Both WordPress and Hugo are powerful tools, each serving a unique purpose. WordPress excels in user-friendliness, customization options, and plugin support, making it ideal for content-rich sites managed by non-developers. Hugo, on the other hand, is perfect for developers or tech-savvy users who value speed, security, and a streamlined, lightweight approach to web development.\nIn the end, the right choice depends on your website’s needs, your technical comfort level, and your priorities. For those who prioritize performance, security, and low maintenance, Hugo is a compelling alternative to WordPress.\nWith these insights, you’ll be better equipped to decide which platform best suits your project and goals. Happy building!\n","link":"https://benoit-gaumard.io/blog/post/2-from-wordpress-to-hugo/","section":"post","tags":["hugo"],"title":"From Wordpress to Hugo website"},{"body":"This article explains how to embed your GitHub code in your Hugo website using a shortcode.\nCreate the shortcode Let’s create a new shortcode. In your Hugo site’s layouts/shortcodes directory (if the folder shortcodes does not exist create it manually), create a file called embedgithubcode.html and paste the following:\n1{{ $file := .Get 0 }} 2{{ with resources.GetRemote $file }} 3 {{ with .Err }} 4 {{ errorf \u0026#34;%s\u0026#34; . }} 5 {{ else }} 6 {{ $lang := path.Ext $file | strings.TrimPrefix \u0026#34;.\u0026#34; }} 7 {{ highlight .Content $lang }} 8 {{ end }} 9{{ else }} 10 {{ errorf \u0026#34;Unable to get remote resource.\u0026#34; }} 11{{ end }} Use the shortcode In any markdown file, you can now use the shortcode like this (note the space I added between {{ to prevent hugo from rendering the shortcode on this page):\n(Note the space I added between {{ to prevent hugo from rendering the shortcode on this page):\n1{ {\u0026lt; embedgithubcode \u0026#34;https://raw.githubusercontent.com/Benoit-Gaumard/azure-policy-aliases-outgridview/refs/heads/main/azure-policy-aliases-outgridview.ps1\u0026#34; \u0026gt;}} Here is the result The script is displayed from my github repository https://github.com/Benoit-Gaumard/azure-policy-aliases-outgridview :\n1# List all namespaces available in Azure Policy 2$AllNamespaces = (Get-AzPolicyAlias -ListAvailable).Namespace | Sort-Object | Get-Unique 3 4# Select the namespaces you want to work with 5$SelectedNamespaces = $null 6$SelectedNamespaces = @() 7 8$AllNamespaces | Out-GridView -Title \u0026#34;Select one or more namespace. Found: $($AllNamespaces.count)\u0026#34; -OutputMode Multiple ` 9| Foreach-object { $SelectedNamespaces += $_ } 10 11# Get all aliases available in the selected namespaces 12$AvailableAliases = $null 13$AvailableAliases = @() 14 15Foreach ($Namespace in $SelectedNamespaces) 16{ 17 $AvailableAliases += (Get-AzPolicyAlias -NamespaceMatch $Namespace).Aliases | Select-Object Name 18} 19 20# List all aliases available in the selected namespaces 21$AvailableAliases | Out-GridView -Title \u0026#34;Available alias for selected ($($SelectedNamespaces.count)): $($SelectedNamespaces)\u0026#34; -OutputMode Single Enjoy!\n","link":"https://benoit-gaumard.io/blog/post/5-how-to-embed-github-code-to-hugo/","section":"post","tags":["hugo"],"title":"How to embed you GitHub code to Hugo using a shortcode?"},{"body":"This article is a template page.\nNotice Bloc More infos here: https://learn.netlify.app/fr/shortcodes/notice/\nNote\n1 Note Text here\nNote Text here\nInfo\n1 Info Text here\nInfo Text here\nTip\n1 Tip Text here\nTip Text here\nWarning\n1 Warning Text here\nWarning Text here\nImage Image\n1Here is the demo: 2![](https://github.com/hediet/vscode-drawio/raw/HEAD/docs/demo.gif) Here is the demo: Image with reduced size\n1\u0026lt;img src=\u0026#34;/images/rssfeed.png\u0026#34; width=\u0026#34;50%\u0026#34; height=\u0026#34;50%\u0026#34;\u0026gt; Web Link\n1Download is available here: [Draw.io Integration – Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio) Download is available here: Draw.io Integration – Visual Studio Marketplace\n","link":"https://benoit-gaumard.io/blog/post/00-template/","section":"post","tags":["Hugo"],"title":"Templates"},{"body":"Learn how to optimize and reduce costs in Azure with practical tips and strategies.\nThroughout my various assignments, I have often heard: \u0026quot;It doesn't matter, I'm not the one paying.\u0026quot; If you have ever taken an Azure subscription with a pay-as-you-go offer, you know that it is essential to control usage costs. Whether for personal use, an SME, or a large group, Azure cost optimization should be part of your cloud strategy.\nCloud adoption and cost reduction are not necessarily associated. The power of the cloud allows you to deploy resources quickly and benefit from the provider's datacenter capabilities to deploy large configurations rapidly.\nWith one click, it is very easy to inflate the bill. The interest of a cloud provider is obviously to encourage and facilitate the use of its services, but it is also advisable to guide its users to make the most of the deployed elements. A satisfied customer is a returning customer 🙂\nBelow are some tips to help you lower the bill:\nUse the right sizes of virtual machines according to needs There are several sizes and options available for Azure virtual machines that you can deploy to run your applications and workloads. These machines are classified by families, so it is advisable to choose the configuration best suited to your needs.\nGeneral purpose Compute optimized Memory optimized Storage optimized GPU optimized High-performance compute Even though the size of the machine can be increased or decreased at any time during its lifecycle, choose the right size from the start. There is no need to provision an F-size machine to host a showcase website for an SME.\nUseful links:\nAzure VM Comparison (azureprice.net) Microsoft Azure VM Selector Block the deployment of certain machine sizes There is a built-in Azure policy called Allowed virtual machine SKUs that allows you to authorize the deployment of certain machine sizes only and thus block the deployment of unauthorized machines. This way, it is easier to control VM deployment costs.\nIn this example, only Basic_A1, Basic_A2, and Basic_A3 size machines are allowed to be deployed. If you try to deploy an unauthorized machine size, the Azure API will send an error message.\nStart/stop machines automatically With the cloud, things have changed; resources are billed on a usage basis. It is therefore necessary to schedule the stop/start of your VMs when they are not in use to save money. By analogy, at home, when you leave a room, you turn off the light; the principle is the same 😉\nThere are several solutions to do this automatically:\nUse the native Azure Auto-shutdown function on each VM Use the Azure Start-Stop VM solution with Azure automation Azure Start-Stop VM Use a custom PowerShell script executed by Azure automation. There are many custom scripts to stop/start your VMs in Azure based on tags. I found an excellent script here: Scheduled Virtual Machine Shutdown Startup that I am reworking and adapting, which will be made available in a future article. Note: Never stop a virtual machine from the OS by doing Start -\u0026gt; Stop because the VM will still be allocated on the hypervisor in Azure, and you will be billed for the machine even if it is turned off. The best practice is to do a Stop from the Azure portal. Only the Stopped (deallocated) status ensures that the VM is properly turned off and that the VM resource is no longer allocated, thus no longer billed.\nUse Azure Advisor As its name suggests, Azure Advisor is an \u0026quot;advisor\u0026quot; that describes best practices to follow to optimize your Azure deployments. It analyzes your configuration and resource usage, then recommends solutions that can help you improve profitability, performance, high availability, and security.\nRecommendations are divided into 5 categories:\nHigh availability: Helps ensure and improve the continuity of your critical applications. For more information, see High availability advisor recommendations. Security: Helps detect threats and vulnerabilities that could lead to security breaches. For more information, see Security advisor recommendations. Performance: To improve the speed of your applications. For more information, see Performance advisor recommendations. Cost: To optimize and reduce your overall Azure spending. For more information, see Cost advisor recommendations. Operational excellence: For process and workflow efficiency, resource management, and deployment. For more information, see Operational excellence advisor recommendations. Use reserved instances (RI) Azure reservations allow you to save money by committing to a one or three-year plan for virtual machines, Azure Blob storage, or Azure Data Lake Storage Gen2, SQL Database compute capacity, Azure Cosmos DB throughput, or other Azure resources. The commitment allows you to get a discount on the resources you use. Reservations can significantly reduce resource costs, up to 72% off pay-as-you-go prices. Reservations provide a billing discount and have no impact on the runtime state of your resources.\nYou commit to consuming x% of Azure resources for 1 or 3 years and you will get a discount. More information available here: Save Compute Costs with Reservations\nUse saving plans Azure feature currently in private preview.\nUse Hybrid benefits The Azure Hybrid Benefit program offers a pricing advantage to customers who already have Microsoft licenses under a Software Assurance (SA) agreement. As a result, these already acquired licenses can be used in Azure. Eligible customers can save up to 40%* on Azure virtual machines (IaaS) and 55% on Azure SQL Database (PaaS) and SQL Server on Azure virtual machines (IaaS) with Azure Hybrid Benefit, or even 80% when combined with Azure reserved instances.\nAll information on Hybrid Benefit is available here: Azure Hybrid Benefit\nAll information on combining reserved instances (RI) + Hybrid benefits is available here: Azure RI + Hybrid Benefits\nNote: It is possible to enforce the use of Hybrid Benefit via an Azure policy available here: Enforce Hybrid Use Benefit\nImplement policies and tags Implementing tags and policies is fundamental before opening the Azure service to users.\nUsing tags in Azure will allow you to know who a resource is assigned to and to contact the person directly if needed (maintenance, billing, patching, etc.). Implementing policies will allow you to audit or constrain users to control the deployment of expensive resources.\nChoose the right type of disk When creating a virtual machine in Azure, several types of disks are offered.\nUltra disk Premium SSD Standard SSD Standard HDD Each type is intended for specific scenarios. Logically, if your application does not require high performance, the storage space of your application is small, or it is only for testing purposes, prefer an HDD disk as it is the cheapest.\nNote: When creating a VM, the Premium SSD type is selected by default. Don't forget to change it to save money.\nChoose the right storage tier for blobs Azure storage offers different access tiers that allow you to store your blob objects in the most cost-effective way.\nThe available access tiers are:\nHot: Optimized for storing frequently accessed data. Cool: Optimized for storing infrequently accessed data and stored for at least 30 days. Archive: Optimized for storing infrequently accessed data and stored for at least 180 days, under flexible latency conditions (a few hours). Note: The hot access tier, offered by default, remains the cheapest.\nPurge unused data/resources (Orphaned resources) When you delete Azure resources, such as a virtual machine, some associated components are not automatically deleted (public IP, disk, vnet, subnet, etc.). Some resources become \u0026quot;orphaned\u0026quot; and potentially billed.\nFiles in a storage account are billed based on the stored volume (GB). It is therefore necessary to regularly clean up to delete certain types of files (obsolete logs, ISO images, etc.).\nNote: It is important to regularly check these resources via a script, for example, to avoid \u0026quot;unnecessary\u0026quot; billing.\nUseful links:\nAzure Orphan Resources Support and train users To avoid any deviations, especially in terms of cost management, supporting and training users is essential.\nMicrosoft offers free courses from its Microsoft Learn platform: Microsoft Learn\nIf you want to train for free on Azure fundamentals, a free training (AZ-900) is available here: Azure Fundamentals\nCertification on Azure technologies is also a plus, as it validates skills and provides recognition in the job market.\nPaid training, depending on your role type (Administrator, Developer, Security, etc.), can be provided directly by Microsoft or accredited organizations.\nBelow is a link to the official Microsoft poster presenting the list of currently available certifications: Microsoft Certification Poster\nUse Azure Cost Management Take advantage of the tools included in your Azure subscription to better leverage the cloud and implement financial governance in your organization.\nTrack resource usage and manage costs with a single, unified view.\nMore information at the following link: Azure Cost Management\nSelect the right Azure region to deploy your resources As of today, Microsoft Azure offers 56 Azure regions worldwide. This allows you to deploy resources wherever you need them. But it can also help you reduce costs. Not all Azure services are available in all Azure regions, and not all Azure services cost the same in each region. Azure resource prices can depend on operating costs and other factors in the specific region. Generally, you want to deploy your virtual machines as close as possible to where you need them and place them in specific Azure regions.\nThis is why deploying and using the same Windows virtual machine in France will not cost the same as in Australia, for example.\nSign an enterprise agreement For large organizations, signing an enterprise agreement (EA) with Microsoft will allow you to consolidate all your Azure subscriptions into a single contract. Generating volume will allow you to negotiate discounts and rebates with Microsoft.\nOther cost optimization topics, in progress: Organize resources with management groups, for example (Test, prod, dev) Committing to long-term consumption (3 to 5 years) can lower the price Select the right region to store data Use Dev/test subscriptions Azure Low Priority VM Choose the right type of workload for your application (VM, container, App Service, etc.): Choose an Azure compute service Use containers Use the pricing calculator Monitor and downsize resources Configure autoscaling Stay informed about new features Use PaaS and SaaS Azure Dev test Set up budgets Use burstable VMs Use Azure spot VMs Management groups Azure policies and initiatives Train cloud operators Conduct regular reviews Understand and review your Azure bill Use third-party tools for FinOps: Cloudyn, etc. Conduct architecture reviews: Azure Well-Architected Review Develop FinOps practices within your company Azure Optimization Engine: The Azure Optimization Engine is an extensible solution designed to generate optimization recommendations for your Azure environment. See it like a fully customizable Azure Advisor. Naming convention RBAC ","link":"https://benoit-gaumard.io/blog/post/4-optimize-and-reduce-costs-in-azure/","section":"post","tags":["cost optimization"],"title":"✨ Optimize and Reduce Costs in Azure"},{"body":"","link":"https://benoit-gaumard.io/blog/tags/cost-optimization/","section":"tags","tags":null,"title":"Cost Optimization"},{"body":"If you want to create your own or contribute to an existing GitHub project, you are on the right page.\nPrerequisites​ IDE (Vscode): Download Visual Studio Code – Mac, Linux, Windows TF executable: Releases · hashicorp/terraform (github.com) or here https://releases.hashicorp.com/terraform/ Azure Subscription Azure CLI: How to install the Azure CLI | Microsoft Learn\nGo​\nPrerequisites Create a storager account and container\nDefine the subscription to store the state\nInstall Terraform\nAdd it to the path\nType to test: terraform –version\n1terraform --version Create a new SPN or MI\nTest connection\nAZ login\n1az login --use-device-code --tenant \u0026lt;your_tenant_id\u0026gt; Set sub if you have multiple subscriptions\n1az account set --subscription \u0026lt;your_subscription_id\u0026gt; Create a container to store the tfstate\nStore Terraform state in Azure Storage Microsoft Learn\n1$RESOURCE_GROUP_NAME=\u0026#39;\u0026lt;your_rg_name\u0026gt;\u0026#39; 2$STORAGE_ACCOUNT_NAME=\u0026#39;\u0026lt;your_sta_name\u0026gt;\u0026#39; 3$CONTAINER_NAME=\u0026#39;tfstate\u0026#39; 4$LOCATION = \u0026#34;westeurope\u0026#34; 5 6# Create resource group 7az group create --name $RESOURCE_GROUP_NAME --location $LOCATION 8 9# Create storage account 10az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob Create the container\nAdd storage blobh data contributor right\nCreate a backend file\n1terraform { 2 backend \u0026#34;azurerm\u0026#34; { 3 resource_group_name = \u0026#34;rg-terraform\u0026#34; 4 storage_account_name = \u0026#34;\u0026lt;your_sta_name\u0026gt;\u0026#34; 5 container_name = \u0026#34;tfstate\u0026#34; 6 key = \u0026#34;mystatefile.terraform.tfstate\u0026#34; 7 } 8} Run the following command to run the configuration:\n1terraform init A new state file will be created in the storage account.\nCreate your terraform code\nValidate the code\n1terraform validate Format the code\n1terraform fmt -recursive Plan or apply\n1terraform apply -auto-approve ","link":"https://benoit-gaumard.io/blog/post/3-set-up-your-first-terraform-environment-on-windows/","section":"post","tags":["Terraform"],"title":"Set Up your first Terraform environment on Windows"},{"body":"If you want to create your own or contribute to an existing GitHub project, you are on the right page.\nAzureRM provider and the remote backend require authentication. The best practice is to disable storage account access key and enable Entra Id (Azure AD) authentication.\nThis storage account configuration will cause the following issue during the terraform init phase\n1Status=403 Code=\u0026#34;KeyBasedAuthenticationNotPermitted\u0026#34; Message=\u0026#34;Key based authentication is not permitted on this storage account. To use Entra Id authentication , here is the configuration to apply on your Terraform configuration.\nOn the backend.tf file, add the use_azuread_auth = true parameter.\n1terraform { 2 backend \u0026#34;azurerm\u0026#34; { 3 resource_group_name = \u0026#34;\u0026lt;YOUR_BACKEND_STORAGE_RESOURCE_GROUP_NAME\u0026gt;\u0026#34; 4 storage_account_name = \u0026#34;\u0026lt;YOUR_BACKEND_STORAGE_ACCOUNT_NAME\u0026gt;\u0026#34; 5 container_name = \u0026#34;\u0026lt;YOUR_BACKEND_CONTAINER_NAME\u0026gt;\u0026#34; 6 key = \u0026#34;\u0026lt;YOUR_BACKEND_KEY_.tfstate\u0026gt;\u0026#34; 7 use_azuread_auth = true 8 } 9} On the provider.tf file, add the storage_use_azuread = true parameter.\n1terraform { 2 required_providers { 3 azurerm = { 4 source = \u0026#34;hashicorp/azurerm\u0026#34; 5 version = \u0026#34;4.1.0\u0026#34; 6 } 7 } 8} 9provider \u0026#34;azurerm\u0026#34; { 10 storage_use_azuread = true 11 skip_provider_registration = true 12 features {} 13} If you look at the storage account activity log. The “List Storage Account Keys” operations are from before use_azuread_auth = true was enabled, and Terraform listed the keys when accessing the state file. After started using Entra ID authentication, the keys were not listed anymore.\nIf using this access method on the Remote backend, your user or service principal needs Storage Data Blob Owner permission on the container scope.\nUsing Entra Id authentication for remote backend is a best practice align with RBAC and least privilege.\nPlease don’t hesitate to comment if there is anything wrong or inaccurate.\n","link":"https://benoit-gaumard.io/blog/post/13-azure-terraform-entra-id-authentication/","section":"post","tags":["Entra ID","Terraform"],"title":"Terraform and Entra Id Authentication"},{"body":"Git is an essential tool for version control and collaboration in software development. This guide covers the fundamental Git commands that every beginner should know. From configuring your user information to managing branches and viewing logs, you'll learn the basics to get started with Git effectively.\nCurrent Config 1git config --list Configure user and email 1git config --global user.name \u0026#34;Your Name\u0026#34; 2git config --global user.email \u0026#34;email@email.com\u0026#34; Clone a repo 1git clone https://github.com/Benoit-Gaumard/ProjectName Get the current branch 1git status Add a folder 1git add . Create a commit (Local) 1git commit -m \u0026#34;feat: bga first commit\u0026#34; Push modifications to the remote branch 1git push Get the last version of the repo from the remote branch 1git pull Change branch 1git checkout mybranch List local branches 1git branch List remote branches 1git branch -r List local and remote branches 1git branch -a Delete a branch (Local) 1git branch -d my-branch-name 2git branch -D my-branch-name Configure repo 1git config –global user.name \u0026#34;Your Name\u0026#34; 2git config –global user.email you@example.com Display repo config 1git config --global --list Logs 1git log -v 2git log -p Create a branch (local) 1git branch my-new-branch 2git checkout -b feat-azure-functions Delete branch (Local) 1git branch -d my-branch Delete branch (Remote) 1git push origin -d my-branch List modified files 1git diff -r --no-commit-id --name-only Misc 1gitk --all ","link":"https://benoit-gaumard.io/blog/post/29-git-basics/","section":"post","tags":["Git","Productivity"],"title":"✨ Git basics"},{"body":"If you're looking to create your own GitHub project or contribute to an existing one, understanding branch naming conventions is crucial. This guide will help you navigate and implement effective branch naming practices.\nBranch Naming Convention 1. Standard Branch Naming Format A commonly used branch naming convention follows this structure:\n1\u0026lt;category\u0026gt;/\u0026lt;issue-number\u0026gt;-\u0026lt;short-description\u0026gt; ✅ Example:\n1feat/123-add-login 2fix/456-bug-navbar 3hotfix/789-fix-crash 2. Common Branch Prefixes Prefix Purpose feat/ New feature development fix/ Bug fixes hotfix/ Critical production fixes chore/ Maintenance tasks (e.g., updating dependencies) refactor/ Code improvements without changing functionality test/ Adding or updating tests docs/ Documentation updates release/ Preparing for a new release ci/ Changes related to CI/CD pipelines ✅ Example:\n1feat/432-add-dark-mode 2fix/567-login-error 3docs/update-readme 4release/1.2.0 3. Best Practices for Naming Branches ✅ Use lowercase letters and hyphens (-) for better readability.\n✅ Include an issue/ticket number if using a tracker (e.g., JIRA, GitHub Issues).\n✅ Keep branch names short yet descriptive.\n✅ Use verbs in active voice (e.g., add-login, fix-navbar).\n❌ Avoid Generic Names:\n1bugfix 2feature1 3new-update ✅ Better Alternatives:\n1fix/404-button-click 2feat/user-dashboard 4. Special Branches Branch Name Purpose main The stable production-ready branch develop The main development branch release/x.y.z Used to prepare for releases hotfix/x.y.z Urgent fixes for production issues ✅ Recommended Workflow:\n1main → develop → feature branches → release → main ✅ Example Workflow in Action:\n1git checkout -b feat/101-user-authentication 2git checkout -b fix/302-broken-signup-button 3git checkout -b hotfix/1.2.3-security-patch 5. Summary ✅ Use prefixes (feat/, fix/, hotfix/, etc.)\n✅ Follow a clear pattern (/-)\n✅ Avoid generic names (feature1, update, fixbug)\n✅ Use Git hooks to enforce naming conventions\n","link":"https://benoit-gaumard.io/blog/post/26-github-branch-naming-convention/","section":"post","tags":["GitHub","Productivity"],"title":"GitHub branch naming convention"},{"body":"If you are looking to create your own GitHub project or contribute to an existing one, understanding commit naming conventions is essential.\nCommit naming convention 1. Use a Consistent Format Maintaining a consistent commit message format improves readability and collaboration.\nStandard Format:\n1\u0026lt;type\u0026gt;(\u0026lt;scope\u0026gt;): \u0026lt;description\u0026gt; 2\u0026lt;type\u0026gt;: \u0026lt;description\u0026gt; ✅ Example:\n1feat(auth): add JWT authentication 2fix(ui): resolve button alignment issue 2. Common Commit Types Type Description feat Introduces a new feature fix Fixes a bug docs Updates documentation style Code style changes (whitespace, formatting, missing semicolons) refactor Code restructuring without changing behavior perf Improves performance test Adds or updates tests chore Maintenance tasks (e.g., package updates, build process changes) ci CI/CD-related changes 3. Writing Clear Commit Messages Use the imperative mood:\n1✅ \u0026#34;fix(login): handle null password error\u0026#34; 2❌ \u0026#34;fixed issue with null password\u0026#34; Keep It Concise:\n✅ Limit subject lines to 50 characters.\n✅ Use present tense (e.g., \u0026quot;fix\u0026quot; instead of \u0026quot;fixed\u0026quot;).\n✅ Wrap the body at 72 characters per line if additional context is needed.\n✅ Keep commits small and focused—avoid committing thousands of lines at once.\n✅ Avoid committing large changes (e.g., 10,000 lines or 100 files) as they are difficult to review.\n4. Writing Meaningful Commit Messages ✅ Good example:\n1feat(api): add rate limiting to prevent abuse Added an IP-based rate-limiting mechanism using Redis to throttle requests and prevent abuse. This will help improve API reliability under high traffic conditions.\nAvoid Generic Commit Messages\n❌ Bad Examples:\n1update 2fix bug 3refactor stuff ✅ Better Alternatives:\n1fix(auth): correct token expiration logic 2chore(deps): update React to v18 5. Use Conventional Commits If your project follows Semantic Versioning, use the Conventional Commits helps automate versioning and changelogs.\n1feat!: introduce breaking change to API The \u0026quot;!\u0026quot; indicates a breaking change.\n6. Optional: Add Emojis for Readability Some teams use emojis to make commit logs visually appealing.\nExample:\n1✨ feat(auth): add OAuth login 2🐛 fix(ui): resolve dropdown bug 3📚 docs(readme): update installation steps 8. Summary By following these commit message conventions, you ensure:\n✅ Clear history\n✅ Easier collaboration\n✅ Better automation (e.g., changelog generation, release management)\nAdopting a structured commit naming convention will make your codebase more maintainable and improve teamwork efficiency.\n","link":"https://benoit-gaumard.io/blog/post/26-github-commit-naming-convention/","section":"post","tags":["GitHub","Productivity"],"title":"GitHub commit naming convention"},{"body":"","link":"https://benoit-gaumard.io/blog/archives/","section":"","tags":null,"title":""},{"body":" Intro Hi there,\nMy name is Benoit Gaumard, a Cloud Consultant and Architect with a focus on Microsoft Azure and related services. As part of the Microsoft company, I’m passionate about cloud architecture, automation, infrastructure as code (IaC), DevOps, and cloud-native solutions. I created this blog to share insights and knowledge about Microsoft technologies.\nHere, I share my experiences and learning, which serves as both a personal reference and a learning tool. I’d love to connect and discuss how I might support your needs!\nBased in Paris, France, I work and live with a focus on cloud solutions.\nThis is a personal blog. The views expressed here are my own and do not reflect those of my employer. All content is for informational purposes only. I am not liable for any errors, omissions, or unavailability of the information provided.\nSkills Some of the technologies I work with:\n\u0026gt;_ Public Cloud (Microsoft Azure) \u0026gt;_ Hybrid Cloud (Microsoft Azure Stack Hub) \u0026gt;_ Governance (Cloud Adoption Framework, Landing zones, Policies) \u0026gt;_ Entra Id (Multi tenancy) \u0026gt;_ Automation (Azure automation, Azure functions, Powershell DSC, Pipelines) \u0026gt;_ Infrastructure as Code (ARM, Terraform, Bicep) \u0026gt;_ DevOps (Azure DevOps, GitHub Actions) \u0026gt;_ Languages (PowerShell, Python, Bash) \u0026gt;_ On Prem Background (Active Directory, Windows Server, Hyper-V, SCVMM, SCCM, ...) And so many things ... Get in touch If you have a project in mind, or just want to connect? You can find me on LinkedIn. Feel free to drop a message, and let’s explore the possibilities together!\nAchievements and Certifications Title Name Badge Azure AI Fundamentals AI-900 Azure Fundamentals AZ-900 Azure Administrator Associate AZ-104 Azure Solutions Architect Expert AZ-300 DevOps Engineer Expert AZ-400 Azure Security Engineer Associate AZ-500 Azure Network Engineer Associate AZ-700 Security, Compliance, and Identity Fundamentals SC-900 Microsoft Cybersecurity Architect SC-100 SC-100 In progress ... I wish you an excellent visit!\n","link":"https://benoit-gaumard.io/blog/about/","section":"","tags":null,"title":"About"},{"body":"az login --use-device-code\naz account set --subscription \u0026quot;\u0026quot;\naz deployment sub validate --location \u0026quot;northeurope\u0026quot; --template-file .\\00-main.bicep az deployment sub validate --location \u0026quot;westeurope\u0026quot; --template-file .\\00-main.bicep --parameters @parameters-dev.json\nbicep --version\naz bicep install az bicep upgrade\n","link":"https://benoit-gaumard.io/blog/page/bicep-basics/","section":"page","tags":null,"title":""},{"body":"","link":"https://benoit-gaumard.io/blog/all-posts/","section":"all-posts","tags":null,"title":"All Posts"},{"body":"","link":"https://benoit-gaumard.io/blog/series/","section":"series","tags":null,"title":"Series"}]