Skip to content

Commit 1096236

Browse files
csanxCristina Sánchez Sánchezoarbusimaastha
authored
doc: Migration guide for mongodbatlas_team.usernames attribute to the mongodbatlas_cloud_user_team_assignment resource (#3588)
* WIP - Migration guide * Migration guide * Changes * Changes * WIP - Examples * WIP - Examples * Migration guide examples * Changed examples directories * Formatting * Typo * Added API Keys * Update examples/migrate_user_team_assignment/module_maintainer/v1/README.md Co-authored-by: maastha <[email protected]> * end of file --------- Co-authored-by: Cristina Sánchez Sánchez <[email protected]> Co-authored-by: Oriol <[email protected]> Co-authored-by: maastha <[email protected]>
1 parent 9f07a9c commit 1096236

File tree

16 files changed

+515
-0
lines changed

16 files changed

+515
-0
lines changed
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
---
2+
page_title: "Migration Guide: Team Usernames Attribute to Cloud User Team Assignment"
3+
---
4+
5+
# Migration Guide: Team Usernames Attribute to Cloud User Team Assignment
6+
7+
**Objective**: Migrate from the deprecated `usernames` attribute on the `mongodbatlas_team` resource to the new `mongodbatlas_cloud_user_team_assignment` resource.
8+
9+
---
10+
11+
## Before you begin
12+
13+
- Create a backup of your [Terraform state file](https://developer.hashicorp.com/terraform/cli/commands/state).
14+
- Ensure you are using the MongoDB Atlas Terraform Provider `2.0.0` or later (version that includes `mongodbatlas_cloud_user_team_assignment` resource).
15+
16+
---
17+
18+
## Why should I migrate?
19+
20+
- **Future Compatibility:** The `usernames` attribute on `mongodbatlas_team` is deprecated and may be removed in future provider versions. Migrating ensures your Terraform configuration remains functional.
21+
- **Flexibility:** Manage teams and user assignments independently, without coupling membership changes to team creation or updates.
22+
- **Clarity:** Clear separation between the `mongodbatlas_team` resource (team definition) and `mongodbatlas_cloud_user_team_assignment` (membership management).
23+
24+
---
25+
26+
## What’s changing?
27+
28+
- `mongodbatlas_team` included a `usernames` argument that allowed assigning users to a team directly inside the resource. This argument is now deprecated.
29+
- New attribute `users` in `mongodbatlas_team` data source can be used to retrieve information about all the users assigned to that team.
30+
- `mongodbatlas_cloud_user_team_assignment` manages the user’s team membership (pending or active) and exposes both `username` and `user_id`. It supports import using either `ORG_ID/TEAM_ID/USERNAME` or `ORG_ID/TEAM_ID/USER_ID`.
31+
32+
---
33+
34+
## From `mongodbatlas_team.usernames` to `mongodbatlas_cloud_user_team_assignment`
35+
36+
### Original configuration
37+
38+
```terraform
39+
locals {
40+
41+
}
42+
43+
resource "mongodbatlas_team" "this" {
44+
org_id = var.org_id
45+
name = "this"
46+
usernames = local.usernames
47+
}
48+
```
49+
50+
---
51+
52+
### Step 1: Use `mongodbatlas_team` data source to retrieve user IDs
53+
54+
We first need to retrieve each user's `user_id` via the new `users` attribute in `mongodbatlas_team` data source.
55+
56+
```terraform
57+
# Use data source to get team members (with user_id)
58+
locals {
59+
60+
team_assignments = {
61+
for user in data.mongodbatlas_team.this.users :
62+
user.id => {
63+
org_id = var.org_id
64+
team_id = mongodbatlas_team.this.team_id
65+
user_id = user.id
66+
}
67+
}
68+
}
69+
70+
resource "mongodbatlas_team" "this" {
71+
org_id = var.org_id
72+
name = var.team_name
73+
usernames = local.usernames
74+
}
75+
76+
data "mongodbatlas_team" "this" {
77+
org_id = var.org_id
78+
team_id = mongodbatlas_team.this.team_id
79+
}
80+
```
81+
82+
---
83+
84+
### Step 2: Add `mongodbatlas_cloud_user_team_assignment` and use import blocks
85+
86+
```terraform
87+
locals {
88+
89+
team_assignments = {
90+
for user in data.mongodbatlas_team.this.users :
91+
user.id => {
92+
org_id = var.org_id
93+
team_id = mongodbatlas_team.this.team_id
94+
user_id = user.id
95+
}
96+
}
97+
}
98+
99+
resource "mongodbatlas_team" "this" {
100+
org_id = var.org_id
101+
name = var.team_name
102+
usernames = local.usernames
103+
}
104+
105+
data "mongodbatlas_team" "this" {
106+
org_id = var.org_id
107+
team_id = mongodbatlas_team.this.team_id
108+
}
109+
110+
# New resource for each (user, team) assignment
111+
resource "mongodbatlas_cloud_user_team_assignment" "this" {
112+
for_each = local.team_assignments
113+
114+
org_id = each.value.org_id
115+
team_id = each.value.team_id
116+
user_id = each.value.user_id # Use user_id instead of username
117+
}
118+
119+
# Import existing team-user relationships into the new resource
120+
import {
121+
for_each = local.team_assignments
122+
123+
to = mongodbatlas_cloud_user_team_assignment.this[each.key]
124+
id = "${each.value.org_id}/${each.value.team_id}/${each.value.user_id}"
125+
}
126+
```
127+
128+
---
129+
130+
## Step 3: Run migration
131+
132+
Run `terraform plan` (you should see **import** operations), then `terraform apply`.
133+
134+
---
135+
136+
## Step 4: Remove deprecated `usernames` from `mongodbatlas_team`
137+
138+
Once the new resources are in place:
139+
140+
```terraform
141+
resource "mongodbatlas_team" "this" {
142+
org_id = var.org_id
143+
name = "this"
144+
# usernames = local.usernames # Remove this line
145+
}
146+
```
147+
148+
Run `terraform plan`. There should be **no changes**.
149+
150+
---
151+
152+
## Step 5: Update any references to `mongodbatlas_team.usernames`
153+
154+
Before:
155+
156+
```terraform
157+
output "team_usernames" {
158+
value = mongodbatlas_team.this.usernames
159+
}
160+
```
161+
162+
After:
163+
164+
```terraform
165+
output "team_usernames" {
166+
value = [for u in data.mongodbatlas_team.this.users : u.username]
167+
}
168+
```
169+
170+
Run `terraform plan`. There should be **no changes**.
171+
172+
---
173+
174+
## Data source migration
175+
176+
If you previously used the `usernames` attribute in the `data.mongodbatlas_team` data source:
177+
178+
**Original:**
179+
180+
```terraform
181+
output "team_usernames" {
182+
description = "Usernames in the MongoDB Atlas team"
183+
value = data.mongodbatlas_team.this.usernames
184+
}
185+
```
186+
187+
**Replace with:**
188+
189+
```terraform
190+
output "team_usernames" {
191+
description = "Usernames in the MongoDB Atlas team"
192+
value = [for u in data.mongodbatlas_team.this.users : u.username]
193+
}
194+
```
195+
196+
Run `terraform plan`. There should be **no changes**.
197+
198+
---
199+
200+
## Migration using Modules
201+
202+
If you are using modules to manage teams and user assignments to teams, migrating from `mongodbatlas_team` to the new pattern requires special attention. Because the old `mongodbatlas_team.usernames` attribute corresponds to `mongodbatlas_cloud_user_team_assignment`, you cannot simply move the resource block inside your module and expect Terraform to handle the migration automatically. This section demonstrates how to migrate from a module using the `mongodbatlas_team` resource to a module using both `mongodbatlas_team` and the new `mongodbatlas_cloud_user_team_assignment` resources.
203+
204+
**Key points for module users:**
205+
- You must use `terraform import` to bring existing user-team assignments into the new resources, even when they are managed inside a module.
206+
- The import command must match the resource address as used in your module (e.g., `module.<module_name>.mongodbatlas_cloud_user_team_assignment.<name>`).
207+
- If you were using a list of usernames in your previous configuration, you also need to include the `mongodbatlas_team` data source and use the new `users` attribute to retrieve the corresponding user IDs, along with team ID, for the import to work correctly.
208+
209+
**Example import blocks for modules**
210+
```terraform
211+
import {
212+
to = module.<module_name>.mongodbatlas_cloud_user_team_assignment.<name>
213+
id = "<ORG_ID>/<TEAM_ID>/<USER_ID>"
214+
}
215+
import {
216+
to = module.<module_name>.mongodbatlas_cloud_user_team_assignment.<name>
217+
id = "<ORG_ID>/<TEAM_ID>/<USERNAME>"
218+
}
219+
```
220+
221+
**Example import commands for modules:**
222+
```shell
223+
terraform import 'module.<module_name>.mongodbatlas_cloud_user_team_assignment.<name>' <ORG_ID>/<TEAM_ID>/<USER_ID>
224+
terraform import 'module.<module_name>.mongodbatlas_cloud_user_team_assignment.<name>' <ORG_ID>/<TEAM_ID>/<USERNAME>
225+
```
226+
227+
### 1. Old Module Usage (Legacy)
228+
229+
```hcl
230+
module "user_team_assignment" {
231+
source = "./old_module"
232+
org_id = var.org_id
233+
team_name = var.team_name
234+
usernames = var.usernames
235+
}
236+
```
237+
238+
### 2. New Module Usage (Recommended)
239+
240+
```hcl
241+
data "mongodbatlas_team" "this" {
242+
org_id = var.org_id
243+
name = var.team_name
244+
}
245+
246+
locals {
247+
team_assigments = {
248+
for user in data.mongodbatlas_team.this.users :
249+
user.id => {
250+
org_id = var.org_id
251+
team_id = data.mongodbatlas_team.this.team_id
252+
user_id = user.id
253+
}
254+
}
255+
}
256+
257+
module "user_team_assignment" {
258+
source = "./new_module"
259+
org_id = var.org_id
260+
team_name = var.team_name
261+
team_assigments = local.team_assigments
262+
}
263+
```
264+
265+
### 3. Migration Steps
266+
267+
1. **Add the new module to your configuration:**
268+
- Add the new module block as shown above, using the same input variables as appropriate.
269+
- Also add the `data.mongodbatlas_team` data source and declare the `team_assignments` local variable to retrieve user IDs and team ID.
270+
271+
2. **Import the existing user-team assignments into the new resources:**
272+
273+
- An `import block` (available in Terraform 1.5 and later) can be used to import the resource and iterate through a list of users, e.g.:
274+
```terraform
275+
import {
276+
for_each = local.team_assigments
277+
278+
to = module.user_team_assignment.mongodbatlas_cloud_user_team_assignment.this[each.key]
279+
id = "${var.org_id}/${data.mongodbatlas_team.this.team_id}/${each.value.user_id}"
280+
}
281+
```
282+
283+
- Alternatively, use the correct resource addresses for your module and each of the user-team assignments:
284+
```shell
285+
terraform import 'module.user_team_assignment.mongodbatlas_cloud_user_team_assignment.this' <ORG_ID>/<TEAM_ID>/<USER_ID>
286+
```
287+
288+
289+
3. **Remove the old module block from your configuration.**
290+
4. **Run `terraform plan` to review the changes.**
291+
- Ensure that Terraform imports the user-team assignments and does not plan to create these.
292+
- Ensure that Terraform does not plan to destroy and recreate the `mongodbatlas_team` resource.
293+
5. **Run `terraform apply` to apply the migration.**
294+
295+
For complete working examples, see:
296+
- [Old module example](https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/examples/migrate_user_team_assignment/module/old_module/)
297+
- [New module example](https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/examples/migrate_user_team_assignment/module/new_module/)
298+
299+
300+
## Notes and tips
301+
302+
- **Import format** for `mongodbatlas_cloud_user_team_assignment`:
303+
304+
```
305+
ORG_ID/TEAM_ID/USERNAME
306+
ORG_ID/TEAM_ID/USER_ID
307+
```
308+
309+
- **Importing inside modules:** Terraform import blocks cannot live inside modules. See ([Terraform issue](https://github.com/hashicorp/terraform/issues/33474)). Each module user must add root-level import blocks for every instance to import.
310+
311+
- After successful migration, ensure **no references to** `mongodbatlas_team.usernames` remain.
312+
313+
## FAQ
314+
**Q: Can I assign the same user to multiple teams?**
315+
A: Yes, simply create multiple `mongodbatlas_cloud_user_team_assignment` resources for each team.
316+
317+
**Q: Where can I find a working example?**
318+
A: See [examples/mongodbatlas_cloud_user_team_assignment/main.tf](https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/examples/mongodbatlas_cloud_user_team_assignment/main.tf).
319+
320+
## Further Resources
321+
- [Cloud User Team Assignment Resource](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/resources/cloud_user_team_assignment)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# MongoDB Atlas Provider — Cloud User Team Assignment Example
2+
3+
Please refer to the [mongodbatlas_cloud_user_assignment example](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/master/examples/mongodbatlas_cloud_user_assignment/README.md) for the example to manage and assigning users to a team using Terraform.
4+
5+
For module usage, see the [module example](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/master/examples/mongodbatlas_cloud_user_team_assignment/module/new_module/README.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Old Module Example: Cloud User Team (Legacy)
2+
3+
This example demonstrates the legacy pattern (prior to v2.0.0) for assigning users to a team using the `mongodbatlas_team` resource. It is intended to show the "before" state for users migrating to the new recommended pattern.
4+
5+
For migration steps, see the [Migration Guide](../../../docs/guides/cloud_user_team_assignment_migration_guide.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
resource "mongodbatlas_team" "this" {
2+
org_id = var.org_id
3+
name = var.team_name
4+
usernames = var.usernames # DEPRECATED
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
variable "org_id" {
2+
description = "MongoDB Atlas Organization ID"
3+
type = string
4+
}
5+
6+
variable "team_name" {
7+
description = "Name of the team"
8+
type = string
9+
}
10+
11+
variable "usernames" {
12+
description = "List of usernames to assign to the team"
13+
type = list(string)
14+
default = []
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
terraform {
2+
required_providers {
3+
mongodbatlas = {
4+
source = "mongodb/mongodbatlas"
5+
version = "~> 1.38" // TODO: CLOUDP-335982: Update to 2.0.0
6+
}
7+
}
8+
required_version = ">= 1.0"
9+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Module Example: Cloud User Team Assignment
2+
3+
This example demonstrates how to use the `mongodbatlas_cloud_user_team_assignment` resource within a Terraform module. It shows how to assign a user to a team using module inputs.
4+
5+
If you are migrating from `mongodbatlas_team` resource, please see the [Migration Guide](../../../docs/guides/cloud_user_team_assignment_migration_guide.md) for important instructions on importing existing resources into your module-managed configuration.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
resource "mongodbatlas_team" "this" {
2+
org_id = var.org_id
3+
name = var.team_name
4+
}
5+
6+
resource "mongodbatlas_cloud_user_team_assignment" "this" {
7+
for_each = var.team_assigments
8+
9+
org_id = each.value.org_id
10+
team_id = each.value.team_id
11+
user_id = each.value.user_id
12+
}

0 commit comments

Comments
 (0)