Radius — Environment Setup
Create a GitHub Environment configured with the cloud credentials and private GHCR state package Radius needs to deploy applications across ephemeral workflow runs. Supports AWS (OIDC via IAM Role) and Azure (OIDC via Workload Identity).
When to use this skill
- "Create a new Radius environment named X"
- "Set up Azure credentials for deploys"
- "Configure AWS for my Radius app"
- "Verify my deploy environment works"
- "Why is the verification workflow failing?"
- "Add a new environment 'staging' pointing at my AKS cluster"
Flow
The canvas drives a short wizard per provider: collect the environment's cloud settings, create and verify a dedicated private/internal GHCR state package with the user's stored GitHub CLI credential, write the package path and cloud settings as GitHub Environment variables, then commit and dispatch the provider's verification workflow. A package bootstrap, visibility, or repository-linkage failure stops setup before verification or automatic deployment.
AWS
- Form inputs: env name, IAM Role ARN, AWS region, account ID, EKS cluster name, optional VPC + subnet IDs (required if the app uses
Radius.Data/mySqlDatabases). These are written as GitHub Environment variables. - Credential + cluster verification: commits/updates
.github/workflows/verify-aws.ymland dispatches it. The workflow logs into AWS via OIDC and runsaws sts get-caller-identity, then runsaws eks update-kubeconfigfor the EKS cluster andkubectl cluster-infoto confirm cluster access. Status is polled and shown live in the canvas.
Azure
- Form inputs: env name, AAD App (client) ID, tenant ID, subscription ID, resource group, AKS cluster name. These are written as GitHub Environment variables.
- Credential + cluster verification: commits/updates
.github/workflows/verify-azure.ymland dispatches it. The workflow runsazure/loginvia OIDC andaz account show, thenaz aks get-credentials+kubelogin convert-kubeconfig+kubectl cluster-infoto confirm AKS access. Status is polled and shown live in the canvas.
How to invoke
When the user asks to create or set up a Radius environment, open the canvas straight to the environment wizard:
open_canvas({
canvasId: "radius",
instanceId: "radius-panel",
input: { page: "environment", repo: "<owner/repo>" }
})
For credentials/OIDC setup:
open_canvas({
canvasId: "radius",
instanceId: "radius-panel",
input: { page: "credentials", repo: "<owner/repo>" }
})
The popup lands directly on the create-environment form for the chosen provider. No navigation needed.
Canvas not opening? If the Radius panel does not appear even though this skill and the Radius plugin are installed, reload extensions (or restart the app) and try again.
Required variables on the GitHub Environment
The verification workflow reads only GitHub Actions variables (vars), never secrets. OIDC eliminates the need to store long-lived cloud credentials.
Common
RADIUS_STATE_BACKEND— explicitly set tooci.RADIUS_STATE_REGISTRY— package-only, per-environment GHCR path used byrad startupandrad shutdown, for exampleghcr.io/example/my-app-radius-state-production-1a2b3c4d5e6f. It does not include:radius-state; the extension derives this value and each GitHub Environment receives a different package.RADIUS_STATE_ARCHIVE— the separate OCI state tag, set toradius-state.
Optional route Gateway policy
RADIUS_ROUTES_EXPOSURE— applies only to the Radius-managed shared Gateway. Leave unset (or setprivate) for the safe defaultClusterIPService with no public IP. Setpubliconly after the user explicitly asks and acknowledges that every routes app in this Radius environment will be exposed through the sharedLoadBalancer.RADIUS_ROUTES_GATEWAY_NAME— selects a user-managed Gateway instead of the Radius-managed stack. When set, the deploy workflow validates the existing Gateway infrastructure and compatible listeners for all declared route kinds but never installs, changes, or adopts it.RADIUS_ROUTES_GATEWAY_NAMESPACE— namespace of the user-managed Gateway. Configure it together withRADIUS_ROUTES_GATEWAY_NAME.
Do not set RADIUS_ROUTES_EXPOSURE together with a user-managed Gateway. New environments do not need an exposure variable: absence intentionally means private. Application evidence such as a source LoadBalancer Service does not change this environment policy.
The managed Contour Gateway supports HTTP and TLS routes. TCP and UDP routes require a compatible user-managed Gateway. When multiple repositories target one cluster, exactly one repository should own the managed Gateway lifecycle; configure the others with RADIUS_ROUTES_GATEWAY_NAME=radius and RADIUS_ROUTES_GATEWAY_NAMESPACE=radius-system so they use it as validation-only BYO infrastructure.
AWS — read by verify-aws.yml:
AWS_ROLE_ARN— ARN of the IAM role the runner assumes via OIDCAWS_REGION— AWS region (e.g.us-west-2)AWS_EKS_CLUSTER_NAME— name of the EKS cluster the workflow verifies access to
AWS — also set from the form for deploys (not read by verification):
AWS_ACCOUNT_ID,RADIUS_VPC_ID,RADIUS_SUBNET_IDS
Azure — read by verify-azure.yml:
AZURE_CLIENT_ID— AAD application (client) IDAZURE_TENANT_ID— Azure tenant IDAZURE_SUBSCRIPTION_ID— Azure subscription IDAZURE_RESOURCE_GROUP— resource group holding the AKS clusterAZURE_AKS_CLUSTER_NAME— name of the AKS cluster the workflow verifies access to
The OIDC trust must already exist on the cloud side before the workflow can authenticate (see Prerequisites below).
Prerequisites on the cloud side
- Local GitHub authentication:
ghmust have a stored keyring login withread:packagesandwrite:packages. The extension deliberately ignores ambientGH_TOKEN/GITHUB_TOKENfor package creation. If needed, rungh auth refresh -s read:packages -s write:packages. - Azure: a federated credential on the AAD app whose subject is exactly
repo:<owner>/<repo>:environment:<environment-name>, audienceapi://AzureADTokenExchange. - AWS: an IAM role trust policy that allows
sts:AssumeRoleWithWebIdentityfromtoken.actions.githubusercontent.comwith audiencests.amazonaws.comand subjectrepo:<owner>/<repo>:environment:<environment-name>.
Common errors and fixes
refusing to allow an OAuth App to create or update workflow .github/workflows/verify-<provider>.yml without 'workflow' scope— the PAT lacksworkflowscope. Rungh auth refresh -s workflow(the extension auto-prefers agh auth tokenover$GITHUB_TOKEN).- "Workflow dispatch accepted, but no new run appeared after 30s" — usually means GitHub hasn't indexed the just-pushed workflow yet. The extension already retries dispatch with backoff; if it still fails, check the Actions tab in the browser.
- Azure OIDC fails with
AADSTS70021: No matching federated identity record found— the federated credential subject on the AAD app doesn't match. Subject must be exactlyrepo:<owner>/<repo>:environment:<env-name>. - AWS OIDC fails with
Not authorized to perform sts:AssumeRoleWithWebIdentity— IAM role trust policy missing or wrong audience. Audience should bests.amazonaws.com, condition ontoken.actions.githubusercontent.com:sub == repo:<owner>/<repo>:environment:<env-name>. - GHCR package bootstrap fails — refresh the stored
ghcredential withread:packagesandwrite:packages. The extension pushes a harmless retainedbootstrapartifact with anorg.opencontainers.image.sourceannotation, then requires the package to be private/internal and linked to the target repository. It never uses a public repository'sGITHUB_TOKENto create the package because that can make the package public.
Verifying after creation
After the canvas reports success, the new env appears in the Envs ▾ dropdown tagged with its provider (AWS/AZURE). Its three state variables select OCI, point to a private/internal GHCR package isolated from every other GitHub Environment, and select that package's radius-state tag. The package retains the harmless bootstrap tag so later workflow runs can add and remove radius-state versions without deleting the configured package. The hub's deploy button enables once both an Application and Environment are selected.
Related files
extension.mjs— environment creation (/api/create-environment), verification workflow generation (generateVerifyWorkflow), and environment variable writes viagh variable set ... --env.- The verification workflow templates are the canonical
verify-aws.yml/verify-azure.yml(both namedRadius - Verify Credentials) hosted inradius-project/ai-extensionsat.github/extension/. The released extension fetches the matching provider template at the full source commit baked into its build, fills theverify-ghcr-pushaction reference with that same immutable SHA, commits it into the target user repo at.github/workflows/verify-<provider>.yml, then dispatches it. A fetch failure is a hard error; no generated verification workflow follows a mutable release ref.