-
Notifications
You must be signed in to change notification settings - Fork 210
Description
Is there an existing issue for this?
- I have searched the existing issues
Provider Version
v1.26.1
Terraform Version
v1.6.6
Terraform Edition
Terraform Open Source (OSS)
Current Behavior
It looks like the refresh state doesn't handle well a diff between the current state and the desire state.
I have create a database user with the terraform provider and deleted it manually. Then, I have tried to re-create it using terraform and the apply failed with the following:
https://cloud.mongodb.com/api/atlas/v2/groups/XXXXXX/databaseUsers/$external/arn:aws:iam::XXXXXX:role%2FchagitNewTest
GET: HTTP 404 Not Found (Error code: "USERNAME_NOT_FOUND") Detail: No user with username arn:aws:iam::XXXX:role/chagitNewTest exists.
Reason: Not Found. Params: [arn:aws:iam::XXXXXX:role/chagitNewTest], BadRequestDetail: `
Upon investigating the code, I found the issue lies in the following snippet in terraform-provider-mongodbatlas/internal/service/databaseuser/resource_database_user.go:
dbUser, httpResponse, err := connV2.DatabaseUsersApi.GetDatabaseUser(ctx, projectID, authDatabaseName, username).Execute()
if err != nil {
// case 404
// deleted in the backend case
if httpResponse != nil && httpResponse.StatusCode == http.StatusNotFound {
resp.State.RemoveResource(ctx)
resp.Diagnostics.AddError("resource not found", err.Error())
return
}
resp.Diagnostics.AddError("error getting database user information", err.Error())
return
}
Instead of setting the resource ID to an empty value (which would allow Terraform to recreate the resource), the code returns an error. This prevents Terraform from recreating the database user.
In other resources, this case is handled by setting an empty ID when the resource is not found. For example, in terraform-provider-mongodbatlas/internal/service/cluster/resource_cluster.go:
cluster, resp, err := connV2.ClustersApi.GetCluster(ctx, projectID, clusterName).Execute()
if err != nil {
if validate.StatusNotFound(resp) {
d.SetId("")
return nil
}
return diag.FromErr(fmt.Errorf(errorRead, clusterName, err))
}
Here, the SetId("") call allows Terraform to handle the resource correctly and recreate it. A similar approach should be implemented for the database user resource.
Terraform configuration to reproduce the issue
terraform {
required_providers {
mongodbatlas = {
source = "mongodb/mongodbatlas"
version = "~> 1.26.1"
}
}
required_version = ">= 1.0.0"
}
provider "mongodbatlas" {
public_key = "XXXXXX" # MongoDB Atlas public API key
private_key = "XXXXXX" # MongoDB Atlas private API key
}
# Create an IAM Role type MongoDB Atlas user
resource "mongodbatlas_database_user" "iam_user" {
username = "arn:aws:iam::XXXXXX:role/chagitNewTest"
aws_iam_type = "ROLE"
project_id = "XXXXXX"
auth_database_name = "$external"
roles {
role_name = "readWriteAnyDatabase" # MongoDB role to grant
database_name = "admin"
}
labels {
key = "environment"
value = "TEST"
}
}Steps To Reproduce
- Run terraform apply to the given configuration.
- Manually delete the created user.
- Try to recreate the user by running terraform apply again.
Logs
mongodbatlas_database_user.iam_user: Refreshing state... [id=XXXXXX]
╷
│ Error: resource not found
│
│ with mongodbatlas_database_user.iam_user,
│ on main.tf line 17, in resource "mongodbatlas_database_user" "iam_user":
│ 17: resource "mongodbatlas_database_user" "iam_user" {
│
│ https://cloud.mongodb.com/api/atlas/v2/groups/XXXX/databaseUsers/$external/arn:aws:iam::XXXX:role%2FchagitNewTest
│ GET: HTTP 404 Not Found (Error code: "USERNAME_NOT_FOUND") Detail: No user with username arn:aws:iam::XXXXX:role/chagitNewTest exists.
│ Reason: Not Found. Params: [arn:aws:iam::XXXXX:role/chagitNewTest], BadRequestDetail:
Code of Conduct
- I agree to follow this project's Code of Conduct