[{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/azure/","section":"Tags","summary":"","title":"Azure","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/posts/","section":"Blog","summary":"","title":"Blog","type":"posts"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/github-actions/","section":"Tags","summary":"","title":"Github-Actions","type":"tags"},{"content":"The idea of writing isn\u0026rsquo;t new. It has been in my head for years, with always an excuse not to. One of the bigger ones was that the site never quite felt right. Bollocks, of course. It is the fear of starting, to be honest. My work gives me enough topics to share: problems, opinions, examples, and plenty of things worth writing down.\nA couple of years ago I started looking for something easy to maintain. Until then I had hosted my photography on WordPress, but it required more infrastructure than I wanted to deal with. Through my own work in Azure I came across Static Web Apps, and that was exactly the level of infrastructure I was looking for. So recently I picked it up again to start building it out.\nThis post covers what I ended up with, why, and a few things worth knowing if you\u0026rsquo;re considering something similar.\nThe stack # Hugo: static site generator Blowfish: Hugo theme Azure Static Web Apps: hosting Azure Blob Storage: media (gallery photos) Terraform with AVM: infrastructure as code GitHub Actions: CI/CD Hugo # So the search for the right technology began. Static site generators was the first term on Google and quickly Hugo and Jekyll were the first to pop up. A quick comparison and test showed my personal preference for Hugo, just a gut feeling, no real other reason.\nOne of the big advantages of static site generators is the immediate feedback loop. You run a local server, make a change, and the page refreshes instantly. I love working that way.\nTechnology decided, now a theme. Here another struggle began. So many options, just like I had with WordPress. Luckily most have demo pages so you can see what they look like before committing. I looked at whether the structural interface was appealing, but also whether the documentation was there to help me along.\nThen I came across Blowfish. The look and feel were right, the documentation was solid, and it allows for quite some customisation if you want to go further.\nTheme decided, time to build the infrastructure.\nAzure Static Web Apps # So for those who are not familiar with Azure Static Web Apps, a little background. It is a hosting service built specifically for, as the name suggests, static sites. So you are able to host sites like Hugo, Jekyll and Gatsby. But you are also able to host sites created with JavaScript frameworks like Angular, React and Vue or Next.js and many more. Last but certainly not least you can integrate a Static Web App with a Function App as an API backend. This gives you quite some options and integrations.\nA few useful things to know:\nFree SSL on both the default hostname and custom domains GitHub Actions integration out of the box. The deploy workflow is generated automatically when you link a repository. Staging environments for pull requests, automatically provisioned and torn down Custom domain support including apex domain, without needing Azure Front Door or a Traffic Manager Authentication via Entra ID and GitHub included out of the box, both available on the free tier The free tier is sufficient for a personal blog. No compute costs, no storage costs for the static assets.\nThe limitation worth knowing: Static Web Apps doesn\u0026rsquo;t support server-side rendering. If you need dynamic content (API backends, database queries), you\u0026rsquo;d need to integrate with Azure Functions or reach for a different hosting model. For a static site hosting a blog that\u0026rsquo;s not a constraint at all.\nTerraform and AVM # As I work with Terraform quite a bit, managing the infrastructure with it was an easy choice. It gives full control over the deployed resources and their configuration, and adding new pieces later is straightforward.\nWriting Terraform for Azure has become much easier since Microsoft is also chipping in with AVM, Azure Verified Modules. It is Microsoft\u0026rsquo;s standard for Terraform (and Bicep) modules for Azure. The modules follow a strict specification and are created and maintained by Microsoft or verified community contributors. You and I can also contribute features and bug fixes, which is part of what keeps the quality up.\nIn practice it gives you modules that are structured consistently and easy to adopt. Instead of writing modules yourself every time, you pick up something that already meets the standard.\nAVM deserves its own post and it will get one. For now, here is what it looks like in practice.\nThe infrastructure for this blog is straightforward. A resource group, a Static Web App, and a storage account for media. Using the AVM module the Static Web App looks like this:\nmodule \u0026#34;static_web_app\u0026#34; { source = \u0026#34;Azure/avm-res-web-staticsite/azurerm\u0026#34; version = \u0026#34;~\u0026gt; 0.6\u0026#34; location = azurerm_resource_group.blog.location name = var.static_web_app_name resource_group_name = azurerm_resource_group.blog.name sku_size = \u0026#34;Free\u0026#34; sku_tier = \u0026#34;Free\u0026#34; tags = var.tags enable_telemetry = false custom_domains = var.custom_domains } The Static Web App resource exposes a deployment API key as an output. That key is what GitHub Actions uses to authenticate deploys. Terraform is not limited to Azure resources. Adding the GitHub provider lets it write the secret directly to GitHub Actions, nothing to copy manually from the portal.\nprovider \u0026#34;github\u0026#34; { owner = var.github_owner } resource \u0026#34;github_actions_secret\u0026#34; \u0026#34;swa_api_token\u0026#34; { repository = var.github_repository secret_name = \u0026#34;AZURE_STATIC_WEB_APPS_API_TOKEN\u0026#34; plaintext_value = module.static_web_app.resource.api_key } The GitHub provider authenticates via the GITHUB_TOKEN environment variable, which you can populate from the gh CLI before running Terraform:\n$env:GITHUB_TOKEN = (gh auth token -u example_username) terraform apply The -u flag targets a specific account. Only needed if you have multiple accounts logged in with the gh CLI. After apply, the secret is in GitHub and the workflow picks it up from there.\nCustom Domains # The Static Web App custom domains are also managed through Terraform. The www subdomain is straightforward. The apex domain is not.\nYou cannot use a CNAME record at the zone apex. It is a DNS standard restriction. SWA validates custom domains using CNAME by default, so pointing takebakker.nl at the SWA hostname that way fails with a 400. The fix is TXT record validation instead:\ncustom_domains = { www = { domain_name = \u0026#34;www.takebakker.nl\u0026#34; } apex = { domain_name = \u0026#34;takebakker.nl\u0026#34; validation_type = \u0026#34;dns-txt-token\u0026#34; } } Run terraform plan and it will output the validation token for the apex domain. Create a TXT record at your DNS provider with that value, then run terraform apply. For the actual routing, use an ALIAS or ANAME record at the apex pointing to the SWA hostname. Not a CNAME.\nGitHub Actions # GitHub Actions are a method to configure actions based on the repository structure and anything you could reach during a action. It gives amazing options to automate stuff. And we did in this case to deploy the Hugo content to the Static Web App.\nThe deployment workflow is simple. Every push to main, hugo builds the site and that build is deployed to the Static Web App via the official Azure/static-web-apps-deploy action.\n- name: Build and Deploy uses: Azure/static-web-apps-deploy@v1 with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }} action: upload app_location: public output_location: \u0026#34;\u0026#34; skip_app_build: true The one non-obvious thing: Hugo can use Git submodules for themes. If your Actions workflow doesn\u0026rsquo;t check out submodules, the build will fail silently. Hugo will build, but the theme won\u0026rsquo;t be there and you\u0026rsquo;ll get an empty site. The fix is adding two lines in the checkout step:\n- uses: actions/checkout@v4 with: submodules: true Pull requests automatically get a staging environment. The action detects the PR context and provisions one. GitHub posts a comment on the PR with the preview URL once the deploy completes. There is a catch though: for that comment to be posted, the job needs pull-requests: write permission. Without it, the deploy succeeds but the URL never appears.\npermissions: pull-requests: write contents: read When the PR is closed the staging environment is torn down automatically. A separate job handles this close_staging which runs the action with action: close.\nclose_staging: name: Close Staging Environment if: github.event_name == \u0026#39;pull_request\u0026#39; \u0026amp;\u0026amp; github.event.action == \u0026#39;closed\u0026#39; runs-on: ubuntu-latest steps: - name: Close staging environment uses: Azure/static-web-apps-deploy@v1 with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} action: close To recap the whole pipeline I used: name: Deploy Blog on: push: branches: - main pull_request: types: [ opened, synchronize, reopened, closed ] branches: - main workflow_dispatch: inputs: close_environment: description: \u0026#39;Name of preview environment to close (leave empty to deploy normally)\u0026#39; required: false default: \u0026#39;\u0026#39; jobs: close_environment: name: Close Preview Environment if: github.event_name == \u0026#39;workflow_dispatch\u0026#39; \u0026amp;\u0026amp; inputs.close_environment != \u0026#39;\u0026#39; runs-on: ubuntu-latest steps: - name: Close named environment uses: Azure/static-web-apps-deploy@v1 with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} action: close deployment_environment: ${{ inputs.close_environment }} build_and_deploy: name: Build and Deploy if: \u0026gt; github.event_name == \u0026#39;push\u0026#39; || (github.event_name == \u0026#39;pull_request\u0026#39; \u0026amp;\u0026amp; github.event.action != \u0026#39;closed\u0026#39;) || (github.event_name == \u0026#39;workflow_dispatch\u0026#39; \u0026amp;\u0026amp; inputs.close_environment == \u0026#39;\u0026#39;) runs-on: ubuntu-latest permissions: pull-requests: write contents: read steps: - name: Checkout (with submodules) uses: actions/checkout@v4 with: submodules: true - name: Setup Hugo uses: peaceiris/actions-hugo@v3 with: hugo-version: latest extended: true - name: Build site run: hugo --minify env: TZ: Europe/Amsterdam - name: Build and Deploy uses: Azure/static-web-apps-deploy@v1 with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }} action: upload app_location: public output_location: \u0026#34;\u0026#34; skip_app_build: true close_staging: name: Close Staging Environment if: github.event_name == \u0026#39;pull_request\u0026#39; \u0026amp;\u0026amp; github.event.action == \u0026#39;closed\u0026#39; runs-on: ubuntu-latest steps: - name: Close staging environment uses: Azure/static-web-apps-deploy@v1 with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} action: close What I\u0026rsquo;d do the same # The Hugo + Static Web Apps combination works well for this use case. Build time is fast, the deploy pipeline is simple, and there\u0026rsquo;s nothing running in production that can break at 2am.\nTerraform for the infrastructure was the right call even for something this small. It helps so be able to quickly build and adjust the configuration. Additionally the state has all details which come in handy such as the DNS configuration for custom domains and the static web app token. The later required for the GitHub action.\nWhat I\u0026rsquo;d approach differently # Blowfish is a good theme but Tailwind CSS complicates customisation. The compiled CSS only includes the utility classes actually used in the theme source. If you want to use a Tailwind class that isn\u0026rsquo;t in the compiled output, you either write plain CSS overrides or you rebuild the Tailwind CSS from source. Both are manageable, but it\u0026rsquo;s worth knowing before you start.\nThe media workflow, uploading photos to Blob Storage manually via Azure CLI or Storage Explorer, is functional but not particularly smooth. I\u0026rsquo;ll probably automate it at some point.\n","date":"20 October 2026","externalUrl":null,"permalink":"/posts/building-this-blog/","section":"Blog","summary":"The idea of writing isn’t new. It has been in my head for years, with always an excuse not to. One of the bigger ones was that the site never quite felt right. Bollocks, of course. It is the fear of starting, to be honest. My work gives me enough topics to share: problems, opinions, examples, and plenty of things worth writing down.\nA couple of years ago I started looking for something easy to maintain. Until then I had hosted my photography on WordPress, but it required more infrastructure than I wanted to deal with. Through my own work in Azure I came across Static Web Apps, and that was exactly the level of infrastructure I was looking for. So recently I picked it up again to start building it out.\n","title":"How This Blog Is Built and Why","type":"posts"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/static-web-apps/","section":"Tags","summary":"","title":"Static-Web-Apps","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/","section":"takebakker.dev","summary":"","title":"takebakker.dev","type":"page"},{"content":"","date":"20 October 2026","externalUrl":null,"permalink":"/tags/terraform/","section":"Tags","summary":"","title":"Terraform","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/drafts/","section":"Drafts","summary":"","title":"Drafts","type":"drafts"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/governance/","section":"Tags","summary":"","title":"Governance","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/networking/","section":"Tags","summary":"","title":"Networking","type":"tags"},{"content":"","date":"11 October 2026","externalUrl":null,"permalink":"/tags/reference/","section":"Tags","summary":"","title":"Reference","type":"tags"},{"content":"Private Endpoint DNS is one of those things that looks straightforward until it isn\u0026rsquo;t. The Azure docs cover the happy path well enough. What they don\u0026rsquo;t cover is what happens in a hub-and-spoke environment where your DNS lives in the hub and your workloads are spread across spokes.\nThis is the setup I run into most often in practice, and it has a few non-obvious gotchas.\nThe problem # When you create a Private Endpoint, Azure creates a private DNS zone and links it to the VNet the endpoint lives in. In a flat network, that\u0026rsquo;s fine. In hub-and-spoke, your workloads in the spoke VNets won\u0026rsquo;t resolve the private IP — they\u0026rsquo;re not linked to that zone, and your central DNS forwarder in the hub doesn\u0026rsquo;t know about it either.\nThe result: traffic from spokes bypasses the private endpoint entirely and hits the public endpoint. You won\u0026rsquo;t always notice immediately, especially if you haven\u0026rsquo;t locked down public access yet.\nWhat actually works # There are two common approaches. Which one fits depends on how your DNS is set up.\nOption 1: Link the private DNS zone to all spokes # The simplest fix if you\u0026rsquo;re managing a small number of spokes. Link privatelink.blob.core.windows.net (or whichever zone applies) to each spoke VNet.\naz network private-dns link vnet create \\ --resource-group rg-dns \\ --zone-name privatelink.blob.core.windows.net \\ --name link-spoke-01 \\ --virtual-network spoke-vnet-01 \\ --registration-enabled false Works, but doesn\u0026rsquo;t scale. Every new spoke needs a new link, and every new service needs a zone linked across all spokes. You end up maintaining a matrix of zones and VNets.\nOption 2: Conditional forwarder on your DNS resolver # The better approach for anything beyond a handful of spokes. Point your Azure DNS Private Resolver (or your custom DNS VM if you\u0026rsquo;re running one) at the privatelink zones using a conditional forwarding rule.\naz dns-resolver forwarding-ruleset rule create \\ --resource-group rg-dns \\ --ruleset-name frs-hub \\ --name rule-blob-private \\ --domain-name \u0026#34;blob.core.windows.net.\u0026#34; \\ --target-dns-servers \u0026#34;[{ipAddress:\u0026#39;168.63.129.16\u0026#39;,port:53}]\u0026#34; This routes all DNS queries for blob.core.windows.net through Azure\u0026rsquo;s internal resolver, which knows about your private DNS zones. Spokes send DNS to the hub resolver, hub resolver forwards to Azure DNS, Azure DNS returns the private IP.\nZone names by service # The zone name differs per service. Common ones:\nService Private DNS Zone Azure Blob Storage privatelink.blob.core.windows.net Azure Key Vault privatelink.vaultcore.azure.net Azure SQL privatelink.database.windows.net Azure Container Registry privatelink.azurecr.io Azure Service Bus privatelink.servicebus.windows.net Full list is in the Microsoft docs — it\u0026rsquo;s long and occasionally changes when new services add Private Endpoint support.\nVerifying it works # Before you close the ticket, verify end-to-end from an actual spoke VM — not from the portal, and not from the hub.\n# From a VM in the spoke nslookup mystorageaccount.blob.core.windows.net # Should return the private IP (10.x.x.x), not a public one # If it returns something like 20.x.x.x you\u0026#39;re still going public If nslookup returns a private IP, dig a bit deeper and confirm the storage account actually has public access disabled:\naz storage account show \\ --name mystorageaccount \\ --query \u0026#34;networkRuleSet.defaultAction\u0026#34; # Should return \u0026#34;Deny\u0026#34; Gotchas # A few things that catch people out:\nZone name for multi-region services: some services use a region-specific zone, not a global one. Azure SQL Managed Instance is a good example. Check before you configure. Split-horizon DNS: if you\u0026rsquo;re running your own DNS on-premises and forwarding to Azure, make sure the forwarder is also picking up the privatelink zones. On-premises DNS won\u0026rsquo;t automatically resolve private endpoints. NSG on the subnet: Private Endpoints ignore NSG rules on the subnet they\u0026rsquo;re deployed in. But other resources connecting to the endpoint are still subject to NSGs on their side. In practice, the DNS resolver with conditional forwarding is the setup that actually holds up as the environment grows. The zone-linking approach turns into a maintenance burden faster than you\u0026rsquo;d expect.\n","date":"11 October 2026","externalUrl":null,"permalink":"/drafts/reference-howto/","section":"Drafts","summary":"Private Endpoint DNS is one of those things that looks straightforward until it isn’t. The Azure docs cover the happy path well enough. What they don’t cover is what happens in a hub-and-spoke environment where your DNS lives in the hub and your workloads are spread across spokes.\nThis is the setup I run into most often in practice, and it has a few non-obvious gotchas.\nThe problem # When you create a Private Endpoint, Azure creates a private DNS zone and links it to the VNet the endpoint lives in. In a flat network, that’s fine. In hub-and-spoke, your workloads in the spoke VNets won’t resolve the private IP — they’re not linked to that zone, and your central DNS forwarder in the hub doesn’t know about it either.\n","title":"Reference: How-To Post","type":"drafts"},{"content":"Terraform state drift is treated as an edge case. In my experience it\u0026rsquo;s more like a regular occurrence that teams aren\u0026rsquo;t monitoring for.\nThe scenario is always some variation of: someone makes a manual change in the portal — usually under time pressure, usually with good intentions — and doesn\u0026rsquo;t update the Terraform code to match. The state file now reflects reality as Terraform last knew it, not reality as it actually is. Next terraform plan shows unexpected changes. The team gets confused, makes it worse, or both.\nWhy \u0026ldquo;just don\u0026rsquo;t make manual changes\u0026rdquo; doesn\u0026rsquo;t work # The correct answer is correct. It\u0026rsquo;s also incomplete.\nIn practice, you\u0026rsquo;re working with teams that have access to the portal, incidents that require immediate action, and situations where Terraform is too slow or not accessible. Policies and training help. They don\u0026rsquo;t eliminate the problem.\nThe more useful question isn\u0026rsquo;t \u0026ldquo;how do we prevent drift\u0026rdquo; — it\u0026rsquo;s \u0026ldquo;how do we detect it quickly and respond cleanly.\u0026rdquo;\nWhat I use # terraform plan run on a schedule, with the output reviewed. Not a full apply, just a plan. If the plan shows unexpected changes, that\u0026rsquo;s the signal. It\u0026rsquo;s simple, it doesn\u0026rsquo;t require extra tooling, and it catches most drift within 24 hours.\n# In your CI pipeline — run this on a schedule terraform plan -detailed-exitcode -out = tfplan # Exit code 2 = changes detected, worth investigating # Exit code 0 = no changes, state matches reality For larger environments with multiple workspaces, something like Atlantis or Spacelift gives you this for free. But even without that, a scheduled pipeline job does the job.\nWhen drift happens anyway # The important thing is what you do next. Specifically: don\u0026rsquo;t panic-apply.\nRunning terraform apply when you don\u0026rsquo;t fully understand the diff will often make things worse. The manual change might be load-bearing — it was made for a reason. Apply without understanding means you might revert something that\u0026rsquo;s keeping a service running.\nThe process I follow:\nIdentify what drifted and why — talk to whoever made the change if you can Decide which is correct: Terraform code or the current resource state If the manual change was wrong, revert it in the portal and let Terraform reconcile If the manual change was right, update the Terraform code to match (terraform import if needed) before applying anything Step 4 is the one that gets skipped. People import the drift and move on without updating the code, which means the same drift happens again next time.\nThe broader point # State drift is a symptom. The root cause is usually one of two things: insufficient access control (people can make changes they shouldn\u0026rsquo;t be making), or Terraform isn\u0026rsquo;t covering the full resource lifecycle (so people use the portal for parts of the workflow that aren\u0026rsquo;t automated yet).\nBoth are worth fixing. But neither fix is instant. Until they\u0026rsquo;re in place, detecting and responding to drift cleanly is the practical alternative to hoping it doesn\u0026rsquo;t happen.\n","date":"11 October 2026","externalUrl":null,"permalink":"/drafts/reference-opinion-post/","section":"Drafts","summary":"Terraform state drift is treated as an edge case. In my experience it’s more like a regular occurrence that teams aren’t monitoring for.\nThe scenario is always some variation of: someone makes a manual change in the portal — usually under time pressure, usually with good intentions — and doesn’t update the Terraform code to match. The state file now reflects reality as Terraform last knew it, not reality as it actually is. Next terraform plan shows unexpected changes. The team gets confused, makes it worse, or both.\n","title":"Reference: Opinion/Experience Post","type":"drafts"},{"content":"We had a policy assignment that looked fine in the portal. Compliance showed 98%. The remaining 2% was a handful of resources flagged for missing tags — known, accepted, moving to remediation next sprint. Nothing alarming.\nThen someone asked why a storage account deployed three weeks ago was still publicly accessible. It wasn\u0026rsquo;t in the non-compliant list. The policy was supposed to deny it.\nIt took a while to figure out why.\nWhat was happening # The policy was assigned at the subscription level with a Deny effect. New resources that don\u0026rsquo;t meet the conditions should fail deployment. That\u0026rsquo;s the expected behaviour, and it was working — we tested it.\nWhat we hadn\u0026rsquo;t accounted for: the storage account had been deployed using an exemption that was added quietly six months earlier for a migration project. The exemption was never removed. The policy evaluated it as excluded, compliance dashboard showed green, and the actual configuration of the resource went unchecked.\nThe exemption didn\u0026rsquo;t show up on the resource\u0026rsquo;s compliance view in a way that made it obvious. You have to know to look for it.\nWhy this matters more than it seems # Policy exemptions are a legitimate tool. Long-running migrations, temporary exceptions while a workload is being refactored — there are real use cases. The problem is they\u0026rsquo;re easy to add and easy to forget.\nIn practice, I\u0026rsquo;ve seen environments where exemptions accumulate over time until the compliance dashboard is effectively meaningless. The numbers look good. The actual security posture isn\u0026rsquo;t what the numbers suggest.\nCompliance percentage is a lagging indicator. It tells you how your known, evaluated resources are doing. It doesn\u0026rsquo;t tell you what\u0026rsquo;s been explicitly excluded from evaluation.\nWhat we changed # A few things came out of this.\nExemption expiry. Azure Policy exemptions support an expiration date. We made it mandatory practice to set one — maximum 90 days. After that they expire automatically and the resource gets re-evaluated. Anything that still needs an exemption gets a deliberate renewal.\nExemption inventory. We added a query to Azure Resource Graph that pulls all active exemptions across subscriptions, with their expiry dates and the person who created them. It runs weekly and the output goes into the governance review.\nPolicyResources | where type == \u0026#34;microsoft.authorization/policyexemptions\u0026#34; | extend expiresOn = properties.expiresOn | extend assignedBy = properties.metadata.createdBy | project subscriptionId, name, expiresOn, assignedBy | order by expiresOn asc Tighter access to exemptions. Creating a policy exemption is a privileged operation. We moved it behind a separate role assignment, so it\u0026rsquo;s not something that can happen without visibility.\nThe takeaway # If you\u0026rsquo;re relying on Policy compliance numbers to understand your security posture, check what\u0026rsquo;s in your exemptions. The 98% you\u0026rsquo;re seeing might be 85% with a quiet 13% sitting in exemptions that nobody is reviewing.\nIt\u0026rsquo;s not a bug in Azure Policy. Exemptions are supposed to work this way. But the governance process around them needs to be as deliberate as the policies themselves.\n","date":"11 October 2026","externalUrl":null,"permalink":"/drafts/reference-problem-post/","section":"Drafts","summary":"We had a policy assignment that looked fine in the portal. Compliance showed 98%. The remaining 2% was a handful of resources flagged for missing tags — known, accepted, moving to remediation next sprint. Nothing alarming.\nThen someone asked why a storage account deployed three weeks ago was still publicly accessible. It wasn’t in the non-compliant list. The policy was supposed to deny it.\nIt took a while to figure out why.\n","title":"Reference: Problem Post","type":"drafts"},{"content":" Take Bakker. Solution architect at Proact. Living in a small village in Drenthe, about 350 people, farmland in every direction. A good place to come home to after a busy day. Together with my partner Nayomie and our dog Zhiva, we have a beautiful place to call home.\nIn practice: I design and build the cloud infrastructure behind the applications organisations use every day. Networking, security boundaries, governance, automation. The stuff that has to just work, silently, at scale. A lot of my time goes into making sure I never have to do the same thing twice.\n18 years in IT, the last 10 focused on Microsoft Azure. 8 as a consultant, 2 as a solution architect. Long enough to have some opinions of my own.\nThis blog has been in my head for years. Always an excuse not to. Bollocks. My work gives me enough material: decisions that weren\u0026rsquo;t obvious, things that broke in interesting ways, approaches that worked better than expected. So I started writing.\nOutside of work I powerlift several times a week. Good way to clear the head. A few times a year I compete as well, just for fun. There is something about competition day that gets you going. Photography has been part of my life since I was young. These days mostly portraits and Urbex, but anything that catches my eye. Some of that ends up here too.\nYou can find me on LinkedIn or GitHub.\n","externalUrl":null,"permalink":"/about/","section":"takebakker.dev","summary":" Take Bakker. Solution architect at Proact. Living in a small village in Drenthe, about 350 people, farmland in every direction. A good place to come home to after a busy day. Together with my partner Nayomie and our dog Zhiva, we have a beautiful place to call home.\nIn practice: I design and build the cloud infrastructure behind the applications organisations use every day. Networking, security boundaries, governance, automation. The stuff that has to just work, silently, at scale. A lot of my time goes into making sure I never have to do the same thing twice.\n","title":"About","type":"page"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/gallery/","section":"Gallery","summary":"","title":"Gallery","type":"gallery"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]