Skip to content

Commit 65ebd38

Browse files
csanxCristina Sánchez Sánchezoarbusimaasthaerabil-mdb
authored
doc: Migration guide for mongodbatlas_project.teams attribute to the mongodbatlas_team_project_assignment resource (#3612)
* Migration guide * WIP - Examples * Outputs * Fix * Format * Apply suggestions from code review Co-authored-by: maastha <[email protected]> * end of file * Update examples/migrate_team_project_assignment/README.md Co-authored-by: Evelyn Rabil <[email protected]> * pr comments --------- Co-authored-by: Cristina Sánchez Sánchez <[email protected]> Co-authored-by: Oriol <[email protected]> Co-authored-by: maastha <[email protected]> Co-authored-by: Evelyn Rabil <[email protected]>
1 parent bede489 commit 65ebd38

File tree

11 files changed

+429
-0
lines changed

11 files changed

+429
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
page_title: "Migration Guide: Project Teams Attribute to Team Project Assignment Resource"
3+
---
4+
5+
# Migration Guide: Project Teams Attribute to Team Project Assignment Resource
6+
7+
**Objective:** Migrate from the deprecated `teams` attribute on the `mongodbatlas_project` resource to the new `mongodbatlas_team_project_assignment` resource.
8+
9+
---
10+
11+
## Before you begin
12+
13+
- **Backup** 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_team_project_assignment` resource).
15+
16+
---
17+
18+
## Why should I migrate?
19+
20+
- **Future compatibility:** The `teams` attribute inside `mongodbatlas_project` is deprecated and will be removed in a future provider release.
21+
- **Separation of concerns:** Manage projects and team-to-project role assignments independently.
22+
- **Clearer diffs:** Role or team modifications won't require re‑applying the entire project resource.
23+
24+
---
25+
26+
## What's changing?
27+
28+
- Historically, `mongodbatlas_project` accepted an inline `teams` block to assign one or more teams to a project with specific roles.
29+
- Now, each project-team role mapping must be managed with `mongodbatlas_team_project_assignment`.
30+
31+
---
32+
33+
## From `mongodbatlas_project.teams` to `mongodbatlas_team_project_assignment`
34+
35+
### Original configuration
36+
37+
```hcl
38+
locals {
39+
project_id = <PROJECT_ID>
40+
team_map = { # team_id => set(role_names)
41+
<TEAM_ID_1> = ["GROUP_OWNER"]
42+
<TEAM_ID_2> = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_WRITE"]
43+
}
44+
}
45+
46+
resource "mongodbatlas_project" "this" {
47+
name = "<PROJECT_NAME>"
48+
org_id = "<ORG_ID>"
49+
project_owner_id = "<OWNER_ID>"
50+
51+
dynamic "teams" {
52+
for_each = local.team_map
53+
content {
54+
team_id = teams.key
55+
role_names = teams.value
56+
}
57+
}
58+
}
59+
```
60+
61+
---
62+
63+
### Step 1: Ignore `teams` and remove from configuration
64+
65+
-> **Note:** The `teams` attribute is a `SetNestedBlock` and cannot be marked `Optional`/`Computed` for a smooth migration. For now, `ignore_changes` is required during Step 1. Support for removing `teams` entirely will come in a future Atlas Provider release.
66+
67+
Replace the `mongodbatlas_project.teams` block with:
68+
69+
```hcl
70+
resource "mongodbatlas_project" "this" {
71+
name = "<PROJECT_NAME>"
72+
org_id = "<ORG_ID>"
73+
project_owner_id = "<OWNER_ID>"
74+
75+
lifecycle {
76+
ignore_changes = ["teams"]
77+
}
78+
}
79+
```
80+
81+
Then run:
82+
83+
```shell
84+
terraform plan
85+
terraform apply
86+
```
87+
88+
This removes the `teams` block from the config but keeps the assignments in Atlas unchanged until we explicitly manage them in new resources.
89+
90+
---
91+
92+
### Step 2: Add the new `mongodbatlas_team_project_assignment` resources
93+
94+
```hcl
95+
resource "mongodbatlas_project" "this" {
96+
name = "<PROJECT_NAME>"
97+
org_id = "<ORG_ID>"
98+
project_owner_id = "<OWNER_ID>"
99+
100+
lifecycle {
101+
ignore_changes = ["teams"]
102+
}
103+
}
104+
105+
resource "mongodbatlas_team_project_assignment" "this" {
106+
for_each = local.team_map
107+
108+
project_id = mongodbatlas_project.this.id
109+
team_id = each.key
110+
role_names = each.value
111+
}
112+
113+
import {
114+
for_each = local.team_map
115+
116+
to = mongodbatlas_team_project_assignment.this[each.key]
117+
id = "${mongodbatlas_project.this.id}/${each.key}"
118+
}
119+
```
120+
121+
Run `terraform plan` (you should see **import** operations), then `terraform apply`.
122+
123+
---
124+
125+
### Step 4: Verify and clean up
126+
127+
- After successful import and apply, `terraform plan` should show **no changes**.
128+
- Keep the `ignore_changes = ["teams"]` lifecycle rule until the provider releases a version without the `teams` argument in `mongodbatlas_project`.
129+
130+
---
131+
132+
## Examples
133+
134+
For complete, working configurations that demonstrate the migration process, see the examples in the provider repository: [migrate_team_project_assignment](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/v2.0.0/examples/migrate_team_project_assignment).
135+
136+
The examples include:
137+
- **v1**: Original configuration using deprecated `teams` attribute in `mongodbatlas_project` resource.
138+
- **v2**: Final configuration using `mongodbatlas_team_project_assignment` resource for team-to-project assignments.
139+
140+
## Notes and tips
141+
142+
- **Import format** for `mongodbatlas_team_project_assignment`:
143+
```
144+
PROJECT_ID/TEAM_ID
145+
```
146+
- **Modules:** Terraform import blocks cannot live inside modules ([Terraform issue](https://github.com/hashicorp/terraform/issues/33474)).
147+
- If you manage team assignments in modules, import each at the root level using the correct resource address (e.g. `module.<name>.mongodbatlas_team_project_assignment.<name>`).
148+
- You can use `terraform plan` to confirm imports before applying.
149+
150+
---
151+
152+
## FAQ
153+
154+
**Q: Do I need to delete the old `teams` from state?**
155+
A: No — using `ignore_changes` ensures they remain in Atlas until the provider removes the field. Then you can drop the lifecycle rule.
156+
157+
---
158+
159+
## Further resources
160+
- [`mongodbatlas_team_project_assignment` docs](https://registry.terraform.io/providers/mongodb/mongodbatlas/latest/docs/resources/team_project_assignment)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Migration Example: Team Project Attribute to Team Project Assignment
2+
3+
This example demonstrates how to migrate from the deprecated `mongodbatlas_project.teams` attribute to the new `mongodbatlas_team_project_assignment` resource.
4+
5+
## Migration Phases
6+
7+
### v1: Initial State (Deprecated Resource)
8+
Shows the original configuration using deprecated `mongodbatlas_project.teams` attribute for team assignments.
9+
10+
### v2: Final State (New Resource Only)
11+
Update the configuration to use `mongodbatlas_team_project_assignment` and migrate away from deprecated `mongodbatlas_project.teams`.
12+
13+
## Usage
14+
15+
1. Start with v1 to understand the original setup with team assignments
16+
2. Apply v2 configuration to import existing assignments with new resource and no longer use deprecated attribute teams
17+
18+
## Prerequisites
19+
20+
- MongoDB Atlas Terraform Provider 2.0.0 or later
21+
- Valid MongoDB Atlas and Team IDs
22+
23+
## Variables
24+
25+
Set these variables for all versions:
26+
27+
```terraform
28+
public_key = <ATLAS_PUBLIC_KEY> # Optional, can use env vars
29+
private_key = <ATLAS_PRIVATE_KEY> # Optional, can use env vars
30+
team_id_1 = <TEAM_ID_1> # Team to assign
31+
team_id_2 = <TEAM_ID_2> # Another team to assign
32+
team_1_roles = ["GROUP_OWNER"]
33+
team_2_roles = ["GROUP_READ_ONLY", "GROUP_DATA_ACCESS_READ_WRITE"]
34+
```
35+
36+
Alternatively, set environment variables:
37+
```bash
38+
export MONGODB_ATLAS_PUBLIC_KEY="your-public-key"
39+
export MONGODB_ATLAS_PRIVATE_KEY="your-private-key"
40+
```
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
############################################################
2+
# v1: Original configuration using deprecated attribute
3+
############################################################
4+
5+
# Map of team IDs to their roles
6+
locals {
7+
team_map = {
8+
(var.team_id_1) = var.team_1_roles
9+
(var.team_id_2) = var.team_2_roles
10+
}
11+
}
12+
13+
# Using deprecated team block inside mongodbatlas_project to assign teams to the project
14+
resource "mongodbatlas_project" "this" {
15+
name = "this"
16+
org_id = var.org_id
17+
18+
dynamic "teams" {
19+
for_each = local.team_map
20+
content {
21+
team_id = teams.key
22+
role_names = teams.value
23+
}
24+
}
25+
}
26+
27+
output "project_teams" {
28+
description = "List of teams assigned to the Atlas project, with their roles"
29+
value = mongodbatlas_project.this.teams
30+
}
31+
32+
output "project_teams_map" {
33+
description = "Map of team IDs to their roles (from teams attribute)"
34+
value = {
35+
for t in mongodbatlas_project.this.teams :
36+
t.team_id => t.role_names
37+
}
38+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
provider "mongodbatlas" {
2+
public_key = var.public_key
3+
private_key = var.private_key
4+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
variable "org_id" {
2+
description = "The ID of the MongoDB Atlas organization"
3+
type = string
4+
}
5+
6+
variable "team_id_1" {
7+
description = "The ID of the first team"
8+
type = string
9+
}
10+
11+
variable "team_1_roles" {
12+
description = "Roles to assign to the first team in the project"
13+
type = list(string)
14+
}
15+
16+
variable "team_id_2" {
17+
description = "The ID of the second team"
18+
type = string
19+
}
20+
21+
variable "team_2_roles" {
22+
description = "Roles to assign to the second team in the project"
23+
type = list(string)
24+
}
25+
26+
variable "public_key" {
27+
description = "Public key for MongoDB Atlas API"
28+
type = string
29+
default = ""
30+
}
31+
variable "private_key" {
32+
description = "Private key for MongoDB Atlas API"
33+
type = string
34+
default = ""
35+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
terraform {
2+
required_version = ">= 1.7.0"
3+
required_providers {
4+
mongodbatlas = {
5+
source = "mongodb/mongodbatlas"
6+
version = "~> 1.0" // TODO: CLOUDP-335982: Update to 2.0.0
7+
}
8+
}
9+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# v2: Final State
2+
3+
This is the final configuration using only the new `mongodbatlas_team_project_assignment` resource while ignoring the deprecated `mongodbatlas_project.teams` attribute.
4+
5+
## What changed from v1
6+
7+
### Resource purpose
8+
- **Old**: Managed through deprecated `mongodbatlas_project.teams` attribute
9+
- **New**: Uses `mongodbatlas_team_project_assignment` resource for team-to-project assignments
10+
11+
### Data source support
12+
- **Old**: Had data source for reading teams attribute
13+
- **New**: Has data source for reading team assignments
14+
15+
## Usage patterns
16+
17+
This configuration demonstrates:
18+
- Basic team assignment to project
19+
- Data source usage for reading assignments
20+
- Output examples showing how to print team assignments in various formats
21+
22+
## Migration complete
23+
24+
At this point, you have successfully migrated from the deprecated `mongodbatlas_project.teams` attribute to the new `mongodbatlas_team_project_assignment` resource. All references to the old attribute have been replaced with the new resource.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
############################################################
2+
# v2: New resource usage
3+
############################################################
4+
5+
# Map of team IDs to their roles
6+
locals {
7+
team_map = {
8+
(var.team_id_1) = var.team_1_roles
9+
(var.team_id_2) = var.team_2_roles
10+
}
11+
}
12+
13+
# Ignore the deprecated teams block in mongodbatlas_project
14+
resource "mongodbatlas_project" "this" {
15+
name = "this"
16+
org_id = var.org_id
17+
lifecycle {
18+
ignore_changes = [teams]
19+
}
20+
}
21+
22+
# Use the new mongodbatlas_team_project_assignment resource
23+
resource "mongodbatlas_team_project_assignment" "this" {
24+
for_each = local.team_map
25+
26+
project_id = mongodbatlas_project.this.id
27+
team_id = each.key
28+
role_names = each.value
29+
}
30+
31+
# Import existing team-project relationships into the new resource
32+
import {
33+
for_each = local.team_map
34+
to = mongodbatlas_team_project_assignment.this[each.key]
35+
id = "${mongodbatlas_project.this.id}/${each.key}"
36+
}
37+
38+
# Example outputs showing team assignments in various formats
39+
output "team_project_assignments" {
40+
description = "List of all team assignments for the MongoDB Atlas project"
41+
value = [
42+
for assignment in mongodbatlas_team_project_assignment.this :
43+
{
44+
team_id = assignment.team_id
45+
role_names = assignment.role_names
46+
}
47+
]
48+
}
49+
50+
output "team_project_assignments_map" {
51+
description = "Map of team_id to role_names for the MongoDB Atlas project"
52+
value = {
53+
for k, assignment in mongodbatlas_team_project_assignment.this :
54+
assignment.team_id => assignment.role_names
55+
}
56+
}
57+
58+
# Data source to read current team assignments for the project
59+
data "mongodbatlas_team_project_assignment" "this" {
60+
project_id = mongodbatlas_project.this.id
61+
team_id = var.team_id_1 # Example for one team; repeat for others as needed
62+
}
63+
64+
output "data_team_project_assignment" {
65+
description = "Data source output for team assignment"
66+
value = {
67+
team_id = data.mongodbatlas_team_project_assignment.this.team_id
68+
project_id = data.mongodbatlas_team_project_assignment.this.project_id
69+
role_names = data.mongodbatlas_team_project_assignment.this.role_names
70+
}
71+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
provider "mongodbatlas" {
2+
public_key = var.public_key
3+
private_key = var.private_key
4+
}

0 commit comments

Comments
 (0)