|
| 1 | +# Design: Modernize .NET APM Agent Linux Test Definitions |
| 2 | + |
| 3 | +**Date:** 2026-06-25 |
| 4 | +**Branch:** `chore/update-dotnet-agent-test-definitions-linux` |
| 5 | +**Status:** Approved (design); pending implementation plan |
| 6 | + |
| 7 | +## Problem |
| 8 | + |
| 9 | +The three existing test definitions that validate the New Relic .NET APM agent on |
| 10 | +Linux all target end-of-life or near-EOL software at multiple layers: |
| 11 | + |
| 12 | +| File | Region | Distro | Runtime installed | App artifact | Agent validation | |
| 13 | +|---|---|---|---|---|---| |
| 14 | +| `test/definitions/apm/dotNet/linux/linux2-aspnetcore5.json` | US | Amazon Linux 2 (EOL ~2026-06) | .NET SDK 7.0 + ASP.NET Core 7.0 via **CentOS 7 RPM** (7.0 EOL) | `net5webapplication` (.NET 5, EOL 2022-05) | **none — no `instrumentations` block** | |
| 15 | +| `test/definitions-eu/apm/dotNet/linux/ubuntu20-apache-aspnetcore.json` | EU | Ubuntu 20.04 Focal (standard support ended 2025-04) | ASP.NET Core 8.0 | `net5webapplication` | infra + `apm/dotNet/linux-systemd` | |
| 16 | +| `test/definitions-jp/apm/dotNet/linux/ubuntu20-apache-aspnetcore.json` | JP | Ubuntu 20.04 Focal | ASP.NET Core 8.0 | `net5webapplication` | infra + `apm/dotNet/linux-systemd` | |
| 17 | + |
| 18 | +The US definition additionally has **no `instrumentations` block**, so it deploys the |
| 19 | +app but never runs the install recipe or validates that the agent installed — it is |
| 20 | +not actually testing the agent. |
| 21 | + |
| 22 | +## Goals |
| 23 | + |
| 24 | +- Test the .NET agent on **modern, supported Linux distros**: Ubuntu 24.04 (Noble) and |
| 25 | + Amazon Linux 2023. |
| 26 | +- Deploy a **.NET 10** ASP.NET Core application (current LTS) instead of .NET 5. |
| 27 | +- Every new definition includes a full `instrumentations` block that runs the install |
| 28 | + recipe and validates the agent (fixing the US gap). |
| 29 | +- Cover **US, EU, and JP** regions. |
| 30 | +- Add the new definitions first; **retire the old ones only after the new ones are |
| 31 | + green** (no coverage gap). |
| 32 | + |
| 33 | +## Non-Goals |
| 34 | + |
| 35 | +- Adding an nginx reverse-proxy variant (Apache only, matching today). |
| 36 | +- arm64 coverage (the `apm/dotNet/linux-systemd` recipe targets `kernelArch: x86_64`). |
| 37 | +- Refactoring deploy scripts beyond what serves this change. |
| 38 | + |
| 39 | +## Key Decisions |
| 40 | + |
| 41 | +1. **Strategy:** Add new definitions + retire old ones after the new set passes. |
| 42 | +2. **Distros:** Ubuntu 24.04 (Noble) and Amazon Linux 2023. |
| 43 | +3. **App runtime target:** .NET 10. |
| 44 | +4. **Regions:** US, EU, JP. |
| 45 | +5. **Region/distro matrix:** US gets both distros; EU and JP each get Ubuntu 24.04. |
| 46 | + → **4 new definitions.** |
| 47 | +6. **Web server:** Apache only. |
| 48 | +7. **App artifact:** external prerequisite — build/upload the .NET 10 zips to the |
| 49 | + `open-install-library-artifacts` S3 bucket outside this repo; **parameterize** the |
| 50 | + deploy scripts to consume them. |
| 51 | +8. **Agent validation:** all four new definitions include the full `instrumentations` |
| 52 | + block. |
| 53 | +9. **Deploy-script structuring:** **Approach A — parameterize the shared |
| 54 | + `apache/deploy-application/dotNet/{debian,rhel}` scripts** with behavior-preserving |
| 55 | + defaults, rather than cloning into version-specific dirs (Approach B). |
| 56 | + |
| 57 | +## Verified Constraints (from exploration) |
| 58 | + |
| 59 | +- `recipes/newrelic/apm/dotNet/linux-systemd.yml` has a wide-open install target |
| 60 | + (`os: linux`, `kernelArch: x86_64`, no platform/version restriction) → **no recipe |
| 61 | + changes needed**; it already accepts Ubuntu 24.04 and AL2023 on x86_64. |
| 62 | +- `recipes/newrelic/infrastructure/awslinux.yml` already supports AL2023 |
| 63 | + (`platformVersion: "(2023\.*)"`). |
| 64 | +- `recipes/newrelic/infrastructure/ubuntu.yml` is version-agnostic → Ubuntu 24.04 fine. |
| 65 | +- AMI name patterns for the target distros are already in use elsewhere in the repo and |
| 66 | + can be reused: |
| 67 | + - Ubuntu Noble: `ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-????????` |
| 68 | + - Amazon Linux 2023: `al2023-ami-2023.*-x86_64` |
| 69 | +- The deployed apps are **prebuilt S3 zips** (`selfcontained-net5webapplication.zip`, |
| 70 | + `frameworkdependent-net5webapplication.zip`); there is **no app source in this repo**. |
| 71 | + |
| 72 | +## Detailed Design |
| 73 | + |
| 74 | +### 1. New test definitions (4 files) |
| 75 | + |
| 76 | +All `t3.micro`, x86_64, two services behind Apache (self-contained `dotnet1` + |
| 77 | +framework-dependent `dotnet2`), each with a full `instrumentations` block validating |
| 78 | +`.NET Agent\s+(installed)`. |
| 79 | + |
| 80 | +| File | Region | Distro | AMI pattern | `user_name` | Infra recipe URL | |
| 81 | +|---|---|---|---|---|---| |
| 82 | +| `test/definitions/apm/dotNet/linux/ubuntu24-apache-aspnetcore.json` | US | Ubuntu 24.04 | `ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-????????` | `ubuntu` | `.../infrastructure/ubuntu.yml` | |
| 83 | +| `test/definitions/apm/dotNet/linux/al2023-apache-aspnetcore.json` | US | Amazon Linux 2023 | `al2023-ami-2023.*-x86_64` | `ec2-user` | `.../infrastructure/awslinux.yml` | |
| 84 | +| `test/definitions-eu/apm/dotNet/linux/ubuntu24-apache-aspnetcore.json` | EU | Ubuntu 24.04 | (noble, as above) | `ubuntu` | `.../infrastructure/ubuntu.yml` | |
| 85 | +| `test/definitions-jp/apm/dotNet/linux/ubuntu24-apache-aspnetcore.json` | JP | Ubuntu 24.04 | (noble, as above) | `ubuntu` | `.../infrastructure/ubuntu.yml` | |
| 86 | + |
| 87 | +Each Ubuntu def's `services` reference: |
| 88 | +- `dotNet/install/ubuntu24` (new runtime-install role) |
| 89 | +- `apache/install/debian` |
| 90 | +- `apache/deploy-application/dotNet/debian` (parameterized for .NET 10), self-contained + framework-dependent |
| 91 | + |
| 92 | +The AL2023 def references: |
| 93 | +- `dotNet/install/al2023` (new runtime-install role) |
| 94 | +- `apache/install/rhel` |
| 95 | +- `apache/deploy-application/dotNet/rhel` (parameterized for .NET 10) |
| 96 | + |
| 97 | +`instrumentations` `recipe_content_url` chains the appropriate infra recipe + |
| 98 | +`.../apm/dotNet/linux-systemd.yml`, with `validate_output: ".NET Agent\\s+\\(installed\\)"`. |
| 99 | + |
| 100 | +### 2. New .NET 10 runtime-install roles |
| 101 | + |
| 102 | +Under `test/deploy/linux/dotNet/install/`: |
| 103 | + |
| 104 | +- **`ubuntu24/`** — mirrors the existing `ubuntu20` role (reads `/etc/os-release`, |
| 105 | + builds the `packages.microsoft.com` `.deb` URL), but installs |
| 106 | + **`aspnetcore-runtime-10.0`** instead of 8.0. |
| 107 | +- **`al2023/`** — installs ASP.NET Core Runtime 10.0 on AL2023 using `dnf`. |
| 108 | + **⚠️ Highest-risk item.** The current `rhel` role uses a CentOS 7 RPM, which is wrong |
| 109 | + for AL2023. The exact package source must be confirmed during implementation |
| 110 | + (candidates, in preference order): AL2023 native `dotnet`/`aspnetcore-runtime-10.0` |
| 111 | + dnf packages; the `packages.microsoft.com` RHEL 9 feed; or `dotnet-install.sh`. |
| 112 | + Treated as an explicit verification spike before the AL2023 definition is finalized. |
| 113 | + |
| 114 | +Only the ASP.NET Core **runtime** is required (the apps are ASP.NET Core web apps); no |
| 115 | +SDK. The self-contained app does not need the runtime, but the framework-dependent app |
| 116 | +does, so the runtime install remains necessary. |
| 117 | + |
| 118 | +### 3. Parameterize `apache/deploy-application/dotNet/{debian,rhel}` |
| 119 | + |
| 120 | +In `onbeforestart/tasks/main.yml` for both `debian` and `rhel`: |
| 121 | + |
| 122 | +- Introduce `dotnet_app_name` (default `net5webapplication`) used to build |
| 123 | + `startup_command` (`/var/www/{{service_id}}/{{dotnet_app_name}}` and |
| 124 | + `.../{{dotnet_app_name}}.dll`). |
| 125 | +- Keep `web_app_url` overridable (already is); the new defs pass the .NET 10 |
| 126 | + self-contained / framework-dependent URLs. Defaults remain the net5 URLs so the |
| 127 | + old defs keep working until retired. |
| 128 | +- Update the human-readable `apache_service_description` strings to be version-neutral |
| 129 | + or driven by a param. |
| 130 | + |
| 131 | +The new definitions pass `dotnet_app_name` + the .NET 10 artifact URLs via service |
| 132 | +`params`. The published entrypoint name inside the new zips must match |
| 133 | +`dotnet_app_name`. |
| 134 | + |
| 135 | +Verify the `rhel` `.service` template's `User=` value is correct for AL2023 (the |
| 136 | +`debian` template hardcodes `User=ubuntu`; the AL2023 service must run as a user that |
| 137 | +exists and owns `/var/www/...`). |
| 138 | + |
| 139 | +### 4. Apache install (reuse) |
| 140 | + |
| 141 | +- Ubuntu 24.04 → existing `apache/install/debian` (apt, `apache2`). Expected to work on |
| 142 | + Noble. |
| 143 | +- AL2023 → existing `apache/install/rhel` (`yum install httpd`; `yum` aliases to `dnf` |
| 144 | + on AL2023). Verify it succeeds on AL2023. |
| 145 | + |
| 146 | +### 5. External prerequisite — .NET 10 app artifacts (out of repo) |
| 147 | + |
| 148 | +Build a .NET 10 ASP.NET Core sample web app in two flavors and upload to the |
| 149 | +`open-install-library-artifacts` S3 bucket (us-west-2): |
| 150 | + |
| 151 | +- `selfcontained-net10webapplication.zip` (self-contained, bundles runtime) |
| 152 | +- `frameworkdependent-net10webapplication.zip` (framework-dependent) |
| 153 | + |
| 154 | +Published entrypoint name (e.g. `net10webapplication` for the dll/executable) must match |
| 155 | +the `dotnet_app_name` the new definitions pass. This work happens outside this repo and |
| 156 | +requires S3 upload access; the repo wiring proceeds against the agreed names, but the |
| 157 | +new tests cannot pass until the artifacts exist. |
| 158 | + |
| 159 | +### 6. Retirement (after the 4 new defs are green) |
| 160 | + |
| 161 | +Delete, only after confirming no other definitions reference them: |
| 162 | + |
| 163 | +- `test/definitions/apm/dotNet/linux/linux2-aspnetcore5.json` |
| 164 | +- `test/definitions-eu/apm/dotNet/linux/ubuntu20-apache-aspnetcore.json` |
| 165 | +- `test/definitions-jp/apm/dotNet/linux/ubuntu20-apache-aspnetcore.json` |
| 166 | +- `test/deploy/linux/dotNet/install/ubuntu20/` and `test/deploy/linux/dotNet/install/rhel/` |
| 167 | + (orphaned runtime-install roles) — **only if** no remaining definition references them. |
| 168 | +- Any net5-only template cruft left behind once the parameterization defaults are no |
| 169 | + longer needed. |
| 170 | + |
| 171 | +## Error Handling / Edge Cases |
| 172 | + |
| 173 | +- **AL2023 .NET 10 install** is the primary failure risk → verification spike (§2). |
| 174 | +- **AL2023 service user** mismatch in the `.service` template → verify (§3). |
| 175 | +- **AMI availability per region** — the noble/al2023 AMI glob patterns must resolve in |
| 176 | + EU and JP regions, not just US. Verify during implementation. |
| 177 | +- **Artifact naming coupling** — deploy-script `dotnet_app_name` must exactly match the |
| 178 | + published entrypoint inside the S3 zips. |
| 179 | + |
| 180 | +## Testing / Validation |
| 181 | + |
| 182 | +- Each new definition is exercised by the repo's existing validator harness (deploy → |
| 183 | + run install recipe → assert `.NET Agent (installed)` → app reachable via Apache). |
| 184 | +- The two-app pattern (self-contained + framework-dependent) preserves coverage of both |
| 185 | + deployment models. |
| 186 | +- Retirement step gated on the new definitions passing in their respective regions. |
| 187 | + |
| 188 | +## Open Items Tracked Into the Plan |
| 189 | + |
| 190 | +1. Confirm the AL2023 .NET 10 ASP.NET Core runtime install path (spike). |
| 191 | +2. Confirm `apache/install/rhel` works unmodified on AL2023. |
| 192 | +3. Confirm the `rhel` `.service` template user for AL2023. |
| 193 | +4. Confirm noble + al2023 AMI patterns resolve in EU and JP. |
| 194 | +5. Agree exact S3 artifact names + published entrypoint name; build/upload (external). |
| 195 | +6. Confirm no other definitions consume the install/deploy roles slated for retirement. |
0 commit comments