Skip to content

Commit 7f0924f

Browse files
manuelap-msftlearn-build-service-prod-01[bot]LauragraCopilot
authored
Add multi-environment guide for declarative agents documentation (#1593)
* Add declarative agents multi-environment guide Add a new docs page (docs/declarative-agents-multi-environment.md) and register it in docs/TOC.yml. The guide explains using .env.* environment files and ${ {VAR} } placeholders to manage target environments and parallel agent versions, includes manifest and packaging examples, CI/CD matrix patterns, naming conventions, and deployment/security recommendations. * Update declarative-agents-multi-environment.md * Update docs/declarative-agents-multi-environment.md Co-authored-by: learn-build-service-prod-01[bot] <274427437+learn-build-service-prod-01[bot]@users.noreply.github.com> * Update docs/declarative-agents-multi-environment.md Co-authored-by: learn-build-service-prod-01[bot] <274427437+learn-build-service-prod-01[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update date and fix sentence structure in documentation Updated the date for the document and corrected a sentence structure. * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: learn-build-service-prod-01[bot] <274427437+learn-build-service-prod-01[bot]@users.noreply.github.com> Co-authored-by: Laura Graham <Lauragra@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 1756ad1 commit 7f0924f

2 files changed

Lines changed: 221 additions & 0 deletions

File tree

docs/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ items:
147147
items:
148148
- name: Create the agent
149149
href: build-declarative-agents.md
150+
- name: Manage environments and versions
151+
href: declarative-agents-multi-environment.md
150152
- name: Customize agent behavior
151153
href: build-declarative-agents-customize-behavior.md
152154
- name: Add knowledge sources
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
---
2+
title: Manage environments and versions for declarative agents
3+
description: Learn how to use environment files in the Microsoft 365 Agents Toolkit to deploy declarative agents across multiple environments and agent versions simultaneously.
4+
author: sebastienlevert
5+
ms.author: slevert
6+
ms.topic: how-to
7+
ms.localizationpriority: medium
8+
ms.date: 06/29/2026
9+
---
10+
11+
# Manage environments and versions for declarative agents
12+
13+
As your declarative agent matures, you need to deploy it to multiple environments—development, staging, and production—and eventually run parallel versions so you can pilot new capabilities without disrupting existing users. Maintaining a separate set of manifest files for every environment and version combination doesn't scale.
14+
15+
The Microsoft 365 Agents Toolkit addresses both requirements, target environment and agent version, with the same mechanism: environment files. By defining one `.env.*` file per deployment target and using `${{VAR_NAME}}` placeholders throughout your manifest, declarative agent file, and `m365agents.yml`, you can provision any environment or version with a single command—`atk provision --env <target>`—without duplicating a single file.
16+
17+
## Two axes, one system
18+
19+
Environment management for declarative agents has two dimensions:
20+
21+
- **Target environments**: The same agent deployed to different tenants or app registrations—development, staging, production, or customer-specific tenants.
22+
- **Agent versions**: Multiple variants of the same agent running in parallel—for example, v1 stable, v2 preview, or an experimental branch.
23+
24+
Both dimensions are handled the same way. You define an environment file for each deployment target, and the `${{VAR_NAME}}` placeholders in your manifest, declarative agent file, and `m365agents.yml` resolve at provision time.
25+
26+
## Model target environments
27+
28+
Most teams deploy to at least two environments—development and production—and many add a staging environment between them. Create one file per environment in the `env/` folder:
29+
30+
```text
31+
env/
32+
├── .env.dev
33+
├── .env.dev.user
34+
├── .env.staging
35+
├── .env.staging.user
36+
├── .env.prod
37+
└── .env.prod.user
38+
```
39+
40+
Each file defines the same variable names with environment-specific values:
41+
42+
```text
43+
# env/.env.staging
44+
TEAMS_APP_ID=33333333-3333-3333-3333-333333333333
45+
AAD_CLIENT_ID=44444444-4444-4444-4444-444444444444
46+
API_BASE_URL=https://api-staging.contoso.com
47+
SHAREPOINT_SITE_URL=https://contoso.sharepoint.com/sites/hr-staging
48+
AGENT_DISPLAY_NAME=HR Onboarding Buddy (Staging)
49+
TEAMSFX_ENV=staging
50+
```
51+
52+
> [!TIP]
53+
> Include the environment name in the agent's display name for non-production tenants. For example, "HR Onboarding Buddy (Staging)" makes it immediately clear to testers which version they're using, which helps avoid confusion when reporting issues.
54+
55+
To target a different environment, pass the `--env` flag to each Agents Toolkit command:
56+
57+
```console
58+
atk provision --env staging
59+
atk deploy --env staging
60+
atk publish --env staging
61+
```
62+
63+
## Model multiple versions
64+
65+
Agent versions follow the same pattern as target environments. Each version is a deployment target with its own environment file. To deploy a version 2 (v2) agent alongside a version 1 (v1) agent in the same production tenant, add a `prod-v2` environment:
66+
67+
```text
68+
env/
69+
├── .env.dev
70+
├── .env.staging
71+
├── .env.prod # v1, the stable one
72+
├── .env.prod-v2 # v2, running side by side
73+
└── ...corresponding .user files
74+
```
75+
76+
Give `.env.prod-v2` a unique Teams app ID so both agents can coexist in the same tenant:
77+
78+
```text
79+
# env/.env.prod-v2
80+
TEAMS_APP_ID=55555555-5555-5555-5555-555555555555
81+
AAD_CLIENT_ID=22222222-2222-2222-2222-222222222222
82+
API_BASE_URL=https://api.contoso.com
83+
SHAREPOINT_SITE_URL=https://contoso.sharepoint.com/sites/hr
84+
AGENT_DISPLAY_NAME=HR Onboarding Buddy (Preview)
85+
AGENT_VERSION=2.0.0
86+
TEAMSFX_ENV=prod-v2
87+
```
88+
89+
Use variables in your manifest for any value that differs between versions:
90+
91+
```json
92+
{
93+
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.24/MicrosoftTeams.schema.json",
94+
"manifestVersion": "1.24",
95+
"id": "${{TEAMS_APP_ID}}",
96+
"version": "${{AGENT_VERSION}}",
97+
"name": {
98+
"short": "${{AGENT_DISPLAY_NAME}}",
99+
"full": "${{AGENT_DISPLAY_NAME}} - Contoso"
100+
},
101+
"developer": {
102+
"name": "Contoso",
103+
"websiteUrl": "${{API_BASE_URL}}"
104+
},
105+
"copilotAgents": {
106+
"declarativeAgents": [
107+
{
108+
"id": "declarativeAgent",
109+
"file": "declarativeAgent.json"
110+
}
111+
]
112+
}
113+
}
114+
```
115+
116+
The result is one manifest file that produces two distinct installable apps in the same tenant. Users who received the preview install see v2; all other users remain on v1.
117+
118+
> [!NOTE]
119+
> The Teams app ID is the key to this pattern. The platform treats apps with different IDs as separate installations, regardless of how much code they share. This separation also enables A/B testing of agent personas without any impact on production users.
120+
121+
## Branch the agent definition itself
122+
123+
When version differences extend beyond variable values (for example, different instructions, a new capability, or a different set of plugins), you have two options for branching the agent definition itself.
124+
125+
**Option A**: Keep a single `declarativeAgent.json` and use variables for the values that differ. This approach works well when the differences are minor, such as a different instructions paragraph or a different SharePoint site URL.
126+
127+
**Option B**: Maintain a separate declarative agent file per version and reference it through a variable in the Teams app manifest:
128+
129+
```json
130+
{
131+
"copilotAgents": {
132+
"declarativeAgents": [
133+
{
134+
"id": "declarativeAgent",
135+
"file": "declarativeAgent.${{AGENT_VARIANT}}.json"
136+
}
137+
]
138+
}
139+
}
140+
```
141+
142+
In `m365agents.yml`, configure the package step to include `${{TEAMSFX_ENV}}` in the output artifact name so each environment produces a distinct zip file:
143+
144+
```yaml
145+
provision:
146+
- uses: teamsApp/zipAppPackage
147+
with:
148+
manifestPath: ./appPackage/manifest.json
149+
outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip
150+
outputFolder: ./appPackage/build
151+
```
152+
153+
When `AGENT_VARIANT=v1`, the build resolves to `declarativeAgent.v1.json`. When `AGENT_VARIANT=v2`, it resolves to `declarativeAgent.v2.json`. Both files are stored in the repository and reviewed in pull requests like any other source file, with no feature flags required.
154+
155+
Because the output zip path includes `${{TEAMSFX_ENV}}`, each environment produces a uniquely named artifact. For example, `appPackage.prod.zip` and `appPackage.prod-v2.zip` are written independently to `./appPackage/build/` and never overwrite each other.
156+
157+
## Automate deployments with CI/CD
158+
159+
To scale this pattern across all environments, use a matrix in GitHub Actions or Azure DevOps to provision each environment from a single workflow:
160+
161+
```yaml
162+
strategy:
163+
matrix:
164+
include:
165+
- target: dev
166+
secret_name: AAD_SECRET_DEV
167+
- target: staging
168+
secret_name: AAD_SECRET_STAGING
169+
- target: prod
170+
secret_name: AAD_SECRET_PROD
171+
- target: prod-v2
172+
secret_name: AAD_SECRET_PROD_V2
173+
steps:
174+
- uses: actions/checkout@v4
175+
- run: npm install -g @microsoft/m365agentstoolkit-cli
176+
- run: atk provision --env ${{ matrix.target }}
177+
env:
178+
SECRET_AAD_CLIENT_SECRET: ${{ secrets[matrix.secret_name] }}
179+
- run: atk deploy --env ${{ matrix.target }}
180+
```
181+
182+
Each matrix job loads the correct `.env.*` file and retrieves its secret from the explicitly mapped GitHub secret. The explicit mapping is required because GitHub secret names only allow uppercase letters, digits, and underscores (for example, a target name like `prod-v2` can't be used directly as a secret name). With this configuration, promoting a change from staging to production becomes a workflow trigger rather than a manual step.
183+
184+
> [!WARNING]
185+
> Don't store production secrets in `.env.prod`. Use `.env.prod.user` for local development and your CI/CD secret store for pipeline runs. Ensure the `.user` files are excluded by `.gitignore` and never committed. Your CI/CD pipeline should inject `SECRET_*` variables at runtime.
186+
187+
## Naming convention
188+
189+
Use the following naming convention for your environment files.
190+
191+
| Pattern | Description |
192+
|---------|-------------|
193+
| `.env.<target>` | Tenant or stage: dev, staging, prod |
194+
| `.env.<target>-<variant>` | Version or branch within a target: prod-v2, prod-experimental |
195+
| `.env.<target>.user` | Secrets for that target, never committed |
196+
| `.env.local` | Agents Toolkit configuration in the project root (auto-generated during provisioning) |
197+
198+
This convention makes the `env/` folder self-documenting. Any team member can determine which environments exist and what each one targets.
199+
200+
## Benefits of this approach
201+
202+
Moving from one manifest per environment to one repo with many environment files changes how your team operates:
203+
204+
- **Parallel versions without code duplication**: Deploy v1 and v2 to the same production tenant for real-user pilots without forking your codebase.
205+
- **Single-command promotion**: Passing `--env prod` is the complete promotion step. No file edits or manual merge steps required.
206+
- **Consistent CI/CD across environments**: A single workflow handles every environment with identical steps, eliminating configuration drift between development and production.
207+
- **Simplified onboarding**: A new team member can get started by filling in `.env.dev.user`. No manifest changes are required.
208+
- **Auditable deployments**: Each environment has a single source-of-truth file. Comparing what changed between `prod` and `prod-v2` is a diff of two files.
209+
210+
This approach treats both target environments and agent versions as deployment targets, using the same tooling and conventions throughout.
211+
212+
## Related content
213+
214+
- [Microsoft 365 Agents Toolkit overview](/microsoftteams/platform/toolkit/agents-toolkit-fundamentals)
215+
- [Agents Toolkit CLI reference](/microsoftteams/platform/toolkit/agents-toolkit-cli)
216+
- [Provision and deploy with Agents Toolkit](/microsoftteams/platform/toolkit/provision)
217+
- [Declarative agent manifest reference](declarative-agent-manifest-1.7.md)
218+
- [Declarative agents overview](overview-declarative-agent.md)
219+
- [Publish agents](publish.md)

0 commit comments

Comments
 (0)