Both environment variables and connection references exist for the same reason: a managed solution should import into Dev, Test, UAT and Prod without the developer editing anything between stages. They achieve that reason in different ways, and teams who conflate them end up with flows that either fail on import or run successfully against the wrong target system.
Here is the split we enforce, and the deployment-settings pattern that ties it together.
What each one is
Connection references are pointers to actual authenticated connections. A connection is the object that holds "here is my SharePoint authentication" or "here is my credential to Acme's REST API." A connection reference is a named slot that a flow uses instead of a direct connection.
When a managed solution imports into a new environment, connection references come in empty. They have to be bound to connections that exist in the target environment. First import pauses for the admin to create those connections; subsequent imports reuse them.
Environment variables are typed values - strings, numbers, JSON, booleans, secrets referenced from Azure Key Vault - that solution-aware code reads at runtime. A flow calls environmentVariables('acme_AcmeApiBaseUrl') and uses the returned value in an HTTP action.
The distinction: a connection reference represents who the flow connects as. An environment variable represents what the flow connects to.
The split we use
Connection reference for:
- The SharePoint site the flow reads from
- The SQL database the integration writes to
- The custom connector to a client's billing system
- Any authenticated service where the connector handles auth
Environment variable for:
- API base URLs for custom REST endpoints hit via HTTP actions
- Feature flags (acme_EnableCouponRedemption)
- Tenant IDs, customer IDs, partition keys used in queries
- Thresholds that differ per environment (rate limits, batch sizes)
- Secret values from Key Vault via secret-type env variables
The smell test: does the flow authenticate with this thing? Connection reference. Is it a value the flow uses? Environment variable.
The deployment-settings.json pattern
When the pipeline imports a managed solution, the target environment needs values for every env variable and bindings for every connection reference. Both come from deployment-settings.json committed to the repo, one per target.
The pipeline step per target:
Secrets live in Key Vault, referenced by Key Vault URI from a secret-type env variable. Nothing sensitive lands in git.
Gotcha: env variable schema name typo
Definitions live inside the solution at Other/EnvironmentVariables.xml. The deployment-settings file references them by SchemaName. If the casing differs, you get either:
- A hard fail at import with "environment variable not found," or
- A silent success where the variable is unset and at runtime returns null
The second is the dangerous one. A flow that hits null for an API base URL will typically construct a malformed URL and fail at the HTTP call, with an error message that points at the HTTP action rather than the missing variable.
We now generate the deployment-settings skeleton from the solution XML instead of hand-writing it:
The team fills in the Values, never the SchemaNames. One class of typo gone.
Gotcha: connection reference not bound after first import
First import into a new environment leaves connection references empty. The solution import succeeds but the flows cannot run - they have no connection to authenticate through.
Two ways to handle this:
- Interactive first import. An admin opens the solution post-import, binds each connection reference, turns flows on.
- Pre-provisioned connections + deployment-settings. Admin creates the connections once, captures the connection IDs, puts them in deployment-settings/prod.json. The pipeline wires the references during the import.
Path 2 requires one-time manual work per connection per environment, then every future deploy is hands-off. Path 1 is fine for low-frequency deploys but burns human time on every release.
The handoff to client admins
When a client takes over admin of an environment we built, they get:
- The deployment-settings file for their env, values they own left blank
- A one-page runbook: what to check after a pipeline run (env variable values, connection reference bindings)
- Their Key Vault URL if secret-type env variables are in use
The clearer the split is in our heads, the cleaner the handoff is for theirs.