{"id":22,"date":"2026-06-06T21:48:47","date_gmt":"2026-06-06T21:48:47","guid":{"rendered":"https:\/\/softwareproduction.eu\/wordpress\/?p=22"},"modified":"2026-06-07T01:22:13","modified_gmt":"2026-06-07T01:22:13","slug":"multi-environment-infrastructure-azure-container-apps-and-the-configuration-system","status":"publish","type":"post","link":"https:\/\/softwareproduction.eu\/?p=22","title":{"rendered":"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em>Sixteenth in a series about migrating from legacy architectures to a modern Nuxt 4 stack.<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The Environment Problem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Any non-trivial application needs multiple environments: development, test, production. In a large enterprise application, feature branches ideally each get an isolated environment so developers can share a live preview without blocking one another.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Configuration is where the real complexity hides. Three environments \u00d7 four services \u00d7 dozens of environment variables \u00d7 secrets \u00d7 scaling rules = hundreds of values that must be correct for every combination. Managing this by hand inevitably leads to deployment failures from miscopied connection strings or wrong environment variables.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The Architecture: Three Environments on Azure Container Apps<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A typical setup runs three distinct environment types, all on Azure Container Apps (ACA):<\/p>\n\n\n\n<pre class=\"mermaid\">flowchart LR\n    subgraph ACA[Azure Container Apps Environment]\n        direction LR\n\n        subgraph FE[Feature Branches]\n            direction TB\n            FE_Title[Per-branch:]\n            FE_SPA[SPA]\n            FE_API[API]\n            FE_Proxy[Proxy]\n            FE_Redis[Redis]\n            FE_Iso[Isolated per branch]\n        end\n\n        subgraph TEST[Test]\n            direction TB\n            T_Title[Shared:]\n            T_SPA[SPA]\n            T_API[API]\n            T_Proxy[Proxy]\n            T_Redis[Redis]\n            T_Notes[Stable integration]\n        end\n\n        subgraph PROD[Production]\n            direction TB\n            P_Title[Shared:]\n            P_SPA[SPA]\n            P_API[API]\n            P_Proxy[Proxy]\n            P_Redis[Redis]\n            P_Notes[Live traffic]\n        end\n    end<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Feature Environments<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In many teams, every feature branch gets its own fully isolated deployment: SPA, API, proxy, and Redis containers. The CI\/CD pipeline provisions on <code>git push<\/code> and tears everything down when the branch is deleted.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Developers share a live URL within minutes of pushing<\/li>\n<li>No shared test environment lock \u2014 multiple features can be tested in parallel<\/li>\n<li>Full isolation \u2014 one branch\u2019s bugs never impact another<\/li>\n<\/ul>\n\n\n\n<pre class=\"mermaid\">flowchart LR\n    subgraph Dev[Developer Workflow]\n        direction LR\n        A[git push to feature branch]\n        B[\"CI\/CD: provision\\nFeature Environment\\n(SPA, API, Proxy, Redis)\"]\n        C[\"Share live URL\\nfor review &amp; QA\"]\n        D[Branch merged\\nand deleted]\n        E[CI\/CD: teardown\\nFeature Environment]\n\n        A --&gt; B --&gt; C --&gt; D --&gt; E\n    end<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Per-Branch Redis<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Each feature branch gets its own Redis container. The pipeline rewrites Redis connection strings in the manifests at deploy time, preventing any cross-branch cache pollution.<\/p>\n\n\n\n<pre class=\"mermaid\">flowchart LR\n    subgraph BranchA[Feature Branch A]\n        A_API[API A]\n        A_R[Redis A]\n        A_API --&gt; A_R\n    end\n\n    subgraph BranchB[Feature Branch B]\n        B_API[API B]\n        B_R[Redis B]\n        B_API --&gt; B_R\n    end\n\n    style BranchA fill:#e8f5e9,stroke:#2e7d32\n    style BranchB fill:#e3f2fd,stroke:#1565c0<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The Configuration Generator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Manually managing hundreds of configuration values does not scale. A <strong>YAML-based configuration system<\/strong> can generate all deployment artifacts from a single source of truth.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Configuration Merge Order<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Configuration values are defined in layers, where later layers override earlier ones:<\/p>\n\n\n\n<pre class=\"mermaid\">flowchart TB\n    L1[\"Layer 1:\\nvalues.yaml\\n(base + test defaults)\"]\n    L2[\"Layer 2:\\nenvironments\/production.yaml\\n(production overrides)\"]\n    L3[\"Layer 3:\\nplatforms\/container-apps.yaml\\n(platform defaults)\"]\n    L4[\"Layer 4:\\nplatforms\/container-apps.production.yaml\\n(platform \u00d7 env)\"]\n    M[\u2b63\\nMerged configuration object]\n    O1[Container Apps\\nJSON manifests]\n    O2[Azure Bicep\\nparameter files]\n    O3[Pipeline\\nvariable files]\n\n    L1 --&gt; L2 --&gt; L3 --&gt; L4 --&gt; M\n    M --&gt; O1\n    M --&gt; O2\n    M --&gt; O3<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To add a new environment variable, define it once in <code>values.yaml<\/code> with a default. If production needs a different value, override it in <code>environments\/production.yaml<\/code>. The generator merges all layers and emits the final artifacts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Generated Artifacts<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The configuration generator produces three kinds of outputs:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Artifact<\/th><th>Purpose<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><strong>Container Apps manifests<\/strong><\/td><td>Complete container spec (env vars, secrets, scaling)<\/td><td><code>container-apps\/spa.test.json<\/code><\/td><\/tr><tr><td><strong>Bicep parameter files<\/strong><\/td><td>Infrastructure parameters (environment name, region)<\/td><td><code>container-apps\/my-app.test.bicepparam<\/code><\/td><\/tr><tr><td><strong>Pipeline variable files<\/strong><\/td><td>CI\/CD variables (image tags, resource names)<\/td><td><code>variables\/common.yml<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<pre class=\"mermaid\">flowchart LR\n    SRC[\"Single source of truth\\n(YAML config)\"]\n    GEN[Configuration generator]\n\n    MAN[Container Apps\\nJSON manifests]\n    BICEP[Bicep parameter files]\n    VARS[Pipeline variable files]\n\n    SRC --&gt; GEN\n    GEN --&gt; MAN\n    GEN --&gt; BICEP\n    GEN --&gt; VARS<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Separation of Infrastructure and Application Configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A critical design choice in large systems: <strong>infrastructure and application configuration are treated as separate concerns<\/strong>.<\/p>\n\n\n\n<pre class=\"mermaid\">flowchart LR\n    subgraph Infra[\"Infrastructure (Bicep)\"]\n        I1[Container Apps Environment]\n        I2[Application Insights]\n        I3[Other platform resources]\n        I_Mgr[\"Managed by:\\nInfrastructure pipeline\\n(runs rarely)\"]\n    end\n\n    subgraph AppCfg[\"Application (JSON Manifests)\"]\n        A1[Container image + tag]\n        A2[Environment variables]\n        A3[\"Secrets (Key Vault refs)\"]\n        A4[Scaling rules]\n        A5[\"Resource limits (CPU\/RAM)\"]\n        A6[Ingress configuration]\n        A_Mgr[\"Managed by:\\nBuild\/deploy pipeline\\n(runs every deployment)\"]\n    end\n\n    Infra --&gt;|\"Provides infrastructure\\nendpoints &amp; resources\"| AppCfg<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Infrastructure \u2014 the Container Apps Environment, monitoring, and other platform resources \u2014 changes rarely and is defined with Bicep. Application configuration \u2014 environment variables, secrets, scaling rules, resource limits \u2014 changes with each deployment and lives in generated JSON manifests.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Risky, infrequent infrastructure changes are decoupled from routine application releases that run multiple times per day.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Secret Management<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sensitive values \u2014 connection strings, API keys, encryption keys \u2014 never live in Git. Secrets are stored in Azure Key Vault and referenced by name in the manifests:<\/p>\n\n\n\n<pre><code class=\"language-yaml\">Manifest (in Git):\n  env:\n    - name: NUXT_REDIS_CONNECTION_STRING\n      secretRef: redis-connection-string    \u2190 reference, not value\n\nKey Vault:\n  redis-connection-string = \"redis:\/\/host:6379,password=...\"\n                                            \u2190 actual value<\/code><\/pre>\n\n\n\n<pre class=\"mermaid\">flowchart LR\n    subgraph Git[Git Repo]\n        M[Manifest\\nsecretRef: redis-connection-string]\n    end\n\n    subgraph KV[Azure Key Vault]\n        S[Secret:\\nredis-connection-string\\n= actual value]\n    end\n\n    subgraph ACA[Azure Container Apps Runtime]\n        R[Container\\nat startup]\n    end\n\n    M -. reference name .-&gt; R\n    S -. value resolution .-&gt; R<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The Container Apps runtime resolves these references at startup. Secret values never show up in CI\/CD logs, Git history, or committed manifests.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Runtime Placeholders<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Some values are only known at deploy time \u2014 for example, the image tag (from the build) or the Application Insights connection string (from infrastructure). Placeholders handle these late-bound values:<\/p>\n\n\n\n<pre><code class=\"language-yaml\">Manifest template:\n  image: myregistry.azurecr.io\/spa:__IMAGE_TAG__\n  env:\n    - name: APPLICATIONINSIGHTS_CONNECTION_STRING\n      value: __APPINSIGHTS_CONNECTION_STRING__\n\nDeploy pipeline substitution:\n  jq '.properties.template.containers[0].image |=\n      gsub(\"__IMAGE_TAG__\"; \"20260602.3\")' manifest.json<\/code><\/pre>\n\n\n\n<pre class=\"mermaid\">sequenceDiagram\n    participant B as Build\n    participant P as Deploy Pipeline\n    participant M as Manifest Template\n    participant ACA as Azure Container Apps\n\n    B-&gt;&gt;P: Produce image tag\\n(e.g. 20260602.3)\n    P-&gt;&gt;M: Load manifest template\\nwith __IMAGE_TAG__ \/ __APPINSIGHTS_CONNECTION_STRING__\n    P-&gt;&gt;P: Use jq to substitute\\nplaceholders with real values\n    P-&gt;&gt;ACA: Apply concrete manifest\n    ACA-&gt;&gt;ACA: Run container with\\nresolved image &amp; settings<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The pipeline replaces placeholders at deploy time using <code>jq<\/code>. Manifests remain deterministic \u2014 the same manifest plus different placeholder values yields different environments.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Blue-Green Deployments<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Test and production environments commonly use blue-green deployments: the new version is deployed alongside the old one, validated, and then traffic is switched.<\/p>\n\n\n\n<pre class=\"mermaid\">flowchart TB\n    subgraph Before[Before]\n        BO[\"Old Revision\\n(v20260601)\\n100% traffic\"]\n    end\n\n    subgraph During[During Deploy]\n        DO[\"Old Revision\\n(v20260601)\\n100% traffic\"]\n        DN[\"New Revision\\n(v20260602)\\n0% traffic\\n(warming up)\"]\n    end\n\n    subgraph After[After Validation]\n        AO[\"Old Revision\\n(v20260601)\\n0% traffic\\n(standby)\"]\n        AN[\"New Revision\\n(v20260602)\\n100% traffic\"]\n    end\n\n    subgraph Rollback[Rollback]\n        RO[\"Switch traffic back\\nto old revision\\n(instant)\"]\n    end<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The old revision remains deployed at 0% traffic. Rolling back is a single traffic flip \u2014 no new deployment, effectively sub-second rollback.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fully Isolated Chains<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Both versions run side by side during the transition. To avoid mixed-version states (for example, a new SPA calling an old API), environment variables are rewritten at deploy time to point to revision-specific hostnames:<\/p>\n\n\n\n<pre><code class=\"language-yaml\">Old Chain: Old Proxy \u2192 Old SPA \u2192 Old API (all on main hostnames)\nNew Chain: New Proxy \u2192 New SPA \u2192 New API (all on revision hostnames)<\/code><\/pre>\n\n\n\n<pre class=\"mermaid\">flowchart LR\n    subgraph Old[\"Old Chain\\n(main hostnames)\"]\n        OP[Old Proxy]\n        OS[Old SPA]\n        OA[Old API]\n        OP --&gt; OS --&gt; OA\n    end\n\n    subgraph New[\"New Chain\\n(revision hostnames)\"]\n        NP[New Proxy]\n        NS[New SPA]\n        NA[New API]\n        NP --&gt; NS --&gt; NA\n    end\n\n    style Old fill:#fff3e0,stroke:#fb8c00\n    style New fill:#e3f2fd,stroke:#1565c0<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Traffic is switched at the proxy level \u2014 a single switch moves all requests to the new chain in one shot.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Production Migration: Front Door Traffic Switching<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For an initial cutover from a legacy system to a new stack, Azure Front Door enables zero-downtime traffic switching:<\/p>\n\n\n\n<pre><code class=\"language-yaml\">Before Go-Live:\n  Front Door \u2192 Old App Service (100% traffic)\n\nDuring Migration:\n  Front Door \u2192 Old App Service (100%)\n  New Container Apps (0%, ready and warmed)\n\nGo-Live:\n  Front Door \u2192 New Container Apps (100%)\n  Old App Service (0%, still running)\n\nIf issues:\n  Front Door \u2192 Old App Service (100%)  \u2190 instant rollback<\/code><\/pre>\n\n\n\n<pre class=\"mermaid\">flowchart TB\n    subgraph Before[Before Go-Live]\n        FD1[Azure Front Door]\n        OA1[Old App Service\\n100% traffic]\n        FD1 --&gt; OA1\n    end\n\n    subgraph Migration[During Migration]\n        FD2[Azure Front Door]\n        OA2[Old App Service\\n100% traffic]\n        NC2[\"New Container Apps\\n0% traffic\\n(ready &amp; warmed)\"]\n        FD2 --&gt; OA2\n        FD2 -. monitoring .- NC2\n    end\n\n    subgraph GoLive[Go-Live]\n        FD3[Azure Front Door]\n        NC3[New Container Apps\\n100% traffic]\n        OA3[\"Old App Service\\n0% traffic\\n(still running)\"]\n        FD3 --&gt; NC3\n    end\n\n    subgraph Issue[If issues]\n        FD4[Azure Front Door]\n        OA4[\"Old App Service\\n100% traffic\\n(instant rollback)\"]\n        FD4 --&gt; OA4\n    end<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Both systems run in parallel. The switch is a Front Door configuration change \u2014 no DNS propagation delays, no cold starts. Rollback is likewise instant.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Lessons Learned<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Generate configuration, don&#8217;t manage it<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Manual configuration management across environments does not scale. Treat it as a code generation problem: define values once, override per environment, and let a generator produce the final artifacts. This removes entire classes of deployment bugs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Separate infrastructure from application deployment<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Infrastructure changes are rare, high-risk, and require planning. Application deployments are frequent and should be low-friction. Coupling the two means either infrastructure changes slow everything down or every deploy becomes risky.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Feature branch environments reshape the workflow<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When every branch has its own live URL, code review turns into live review. Stakeholders can exercise features before they merge. QA can work in parallel with development. The infrastructure cost is trivial compared to the productivity gain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Blue-green is worth the complexity<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Being able to deploy a new version, validate it under real traffic conditions, and then flip traffic with instant rollback changes the risk profile of releases. Deployments become uneventful.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Article 12<\/strong>: <em>Security in a Nuxt SSR App \u2014 CSRF, Azure AD, CSP, and More<\/em> \u2014 The security layers that protect a server-rendered application.<\/li>\n<li><strong>Article 13<\/strong>: <em>Observability and Distributed Tracing \u2014 Application Insights End-to-End<\/em> \u2014 How every request is traced across all layers.<\/li>\n<li><strong>Article 14<\/strong>: <em>AI-Assisted Development \u2014 MCP, Debug Chatbot, and the Shared Language of the Codebase<\/em> \u2014 Making AI assistants genuinely useful for live debugging.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Munir Husseini is a software architect specializing in full-stack TypeScript, .NET, and cloud-native architectures.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sixteenth in a series about migrating from legacy architectures to a modern Nuxt 4 stack. The Environment Problem Any non-trivial application needs multiple environments: development, test, production. In a large enterprise application, feature branches ideally each get an isolated environment so developers can share a live preview without blocking one another. Configuration is where the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":240,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5],"tags":[],"class_list":["post-22","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-advanced-web-app-with-nuxt-and-net"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System - Software Production<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/softwareproduction.eu\/?p=22\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System - Software Production\" \/>\n<meta property=\"og:description\" content=\"Sixteenth in a series about migrating from legacy architectures to a modern Nuxt 4 stack. The Environment Problem Any non-trivial application needs multiple environments: development, test, production. In a large enterprise application, feature branches ideally each get an isolated environment so developers can share a live preview without blocking one another. Configuration is where the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/softwareproduction.eu\/?p=22\" \/>\n<meta property=\"og:site_name\" content=\"Software Production\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-06T21:48:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-07T01:22:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/06\/16-multi-environment-infrastructure.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1880\" \/>\n\t<meta property=\"og:image:height\" content=\"1253\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Munir Husseini\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Munir Husseini\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22\"},\"author\":{\"name\":\"Munir Husseini\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#\\\/schema\\\/person\\\/fec48f54713e1bd117640fb9b748802f\"},\"headline\":\"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System\",\"datePublished\":\"2026-06-06T21:48:47+00:00\",\"dateModified\":\"2026-06-07T01:22:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22\"},\"wordCount\":894,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/softwareproduction.eu\\\/wordpress\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/16-multi-environment-infrastructure.jpg\",\"articleSection\":[\"Advanced Web App with Nuxt and .NET\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22\",\"url\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22\",\"name\":\"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System - Software Production\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/softwareproduction.eu\\\/wordpress\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/16-multi-environment-infrastructure.jpg\",\"datePublished\":\"2026-06-06T21:48:47+00:00\",\"dateModified\":\"2026-06-07T01:22:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/softwareproduction.eu\\\/?p=22\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#primaryimage\",\"url\":\"https:\\\/\\\/softwareproduction.eu\\\/wordpress\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/16-multi-environment-infrastructure.jpg\",\"contentUrl\":\"https:\\\/\\\/softwareproduction.eu\\\/wordpress\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/16-multi-environment-infrastructure.jpg\",\"width\":1880,\"height\":1253},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/?p=22#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/softwareproduction.eu\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#website\",\"url\":\"https:\\\/\\\/softwareproduction.eu\\\/\",\"name\":\"Softwareproduction\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/softwareproduction.eu\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#organization\",\"name\":\"Munir Husseini\",\"url\":\"https:\\\/\\\/softwareproduction.eu\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/softwareproduction.eu\\\/wordpress\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/softwareproduction-logo-32.png\",\"contentUrl\":\"https:\\\/\\\/softwareproduction.eu\\\/wordpress\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/softwareproduction-logo-32.png\",\"width\":32,\"height\":32,\"caption\":\"Munir Husseini\"},\"image\":{\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/softwareproduction.eu\\\/#\\\/schema\\\/person\\\/fec48f54713e1bd117640fb9b748802f\",\"name\":\"Munir Husseini\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b07845732d4d7bddfc43e608ae6662d564a14b35706dfae0c9610071d978f54e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b07845732d4d7bddfc43e608ae6662d564a14b35706dfae0c9610071d978f54e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b07845732d4d7bddfc43e608ae6662d564a14b35706dfae0c9610071d978f54e?s=96&d=mm&r=g\",\"caption\":\"Munir Husseini\"},\"sameAs\":[\"https:\\\/\\\/softwareproduction.eu\\\/\"],\"url\":\"https:\\\/\\\/softwareproduction.eu\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System - Software Production","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/softwareproduction.eu\/?p=22","og_locale":"en_US","og_type":"article","og_title":"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System - Software Production","og_description":"Sixteenth in a series about migrating from legacy architectures to a modern Nuxt 4 stack. The Environment Problem Any non-trivial application needs multiple environments: development, test, production. In a large enterprise application, feature branches ideally each get an isolated environment so developers can share a live preview without blocking one another. Configuration is where the [&hellip;]","og_url":"https:\/\/softwareproduction.eu\/?p=22","og_site_name":"Software Production","article_published_time":"2026-06-06T21:48:47+00:00","article_modified_time":"2026-06-07T01:22:13+00:00","og_image":[{"width":1880,"height":1253,"url":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/06\/16-multi-environment-infrastructure.jpg","type":"image\/jpeg"}],"author":"Munir Husseini","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Munir Husseini","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/softwareproduction.eu\/?p=22#article","isPartOf":{"@id":"https:\/\/softwareproduction.eu\/?p=22"},"author":{"name":"Munir Husseini","@id":"https:\/\/softwareproduction.eu\/#\/schema\/person\/fec48f54713e1bd117640fb9b748802f"},"headline":"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System","datePublished":"2026-06-06T21:48:47+00:00","dateModified":"2026-06-07T01:22:13+00:00","mainEntityOfPage":{"@id":"https:\/\/softwareproduction.eu\/?p=22"},"wordCount":894,"commentCount":0,"publisher":{"@id":"https:\/\/softwareproduction.eu\/#organization"},"image":{"@id":"https:\/\/softwareproduction.eu\/?p=22#primaryimage"},"thumbnailUrl":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/06\/16-multi-environment-infrastructure.jpg","articleSection":["Advanced Web App with Nuxt and .NET"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/softwareproduction.eu\/?p=22#respond"]}]},{"@type":"WebPage","@id":"https:\/\/softwareproduction.eu\/?p=22","url":"https:\/\/softwareproduction.eu\/?p=22","name":"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System - Software Production","isPartOf":{"@id":"https:\/\/softwareproduction.eu\/#website"},"primaryImageOfPage":{"@id":"https:\/\/softwareproduction.eu\/?p=22#primaryimage"},"image":{"@id":"https:\/\/softwareproduction.eu\/?p=22#primaryimage"},"thumbnailUrl":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/06\/16-multi-environment-infrastructure.jpg","datePublished":"2026-06-06T21:48:47+00:00","dateModified":"2026-06-07T01:22:13+00:00","breadcrumb":{"@id":"https:\/\/softwareproduction.eu\/?p=22#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/softwareproduction.eu\/?p=22"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/softwareproduction.eu\/?p=22#primaryimage","url":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/06\/16-multi-environment-infrastructure.jpg","contentUrl":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/06\/16-multi-environment-infrastructure.jpg","width":1880,"height":1253},{"@type":"BreadcrumbList","@id":"https:\/\/softwareproduction.eu\/?p=22#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/softwareproduction.eu\/"},{"@type":"ListItem","position":2,"name":"Multi-Environment Infrastructure \u2014 Azure Container Apps and the Configuration System"}]},{"@type":"WebSite","@id":"https:\/\/softwareproduction.eu\/#website","url":"https:\/\/softwareproduction.eu\/","name":"Softwareproduction","description":"","publisher":{"@id":"https:\/\/softwareproduction.eu\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/softwareproduction.eu\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/softwareproduction.eu\/#organization","name":"Munir Husseini","url":"https:\/\/softwareproduction.eu\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/softwareproduction.eu\/#\/schema\/logo\/image\/","url":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/05\/softwareproduction-logo-32.png","contentUrl":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/05\/softwareproduction-logo-32.png","width":32,"height":32,"caption":"Munir Husseini"},"image":{"@id":"https:\/\/softwareproduction.eu\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/softwareproduction.eu\/#\/schema\/person\/fec48f54713e1bd117640fb9b748802f","name":"Munir Husseini","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b07845732d4d7bddfc43e608ae6662d564a14b35706dfae0c9610071d978f54e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b07845732d4d7bddfc43e608ae6662d564a14b35706dfae0c9610071d978f54e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b07845732d4d7bddfc43e608ae6662d564a14b35706dfae0c9610071d978f54e?s=96&d=mm&r=g","caption":"Munir Husseini"},"sameAs":["https:\/\/softwareproduction.eu\/"],"url":"https:\/\/softwareproduction.eu\/?author=1"}]}},"jetpack_featured_media_url":"https:\/\/softwareproduction.eu\/wordpress\/wp-content\/uploads\/2026\/06\/16-multi-environment-infrastructure.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=\/wp\/v2\/posts\/22","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=22"}],"version-history":[{"count":9,"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=\/wp\/v2\/posts\/22\/revisions"}],"predecessor-version":[{"id":241,"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=\/wp\/v2\/posts\/22\/revisions\/241"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=22"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=22"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/softwareproduction.eu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}