Skip to content

Commit

Permalink
INTMDB-163: Wrong order for PrivateLink Endpoint Service and detects …
Browse files Browse the repository at this point in the history
…unnecessary changes (#388)

* fix: added parameters provider name and region for private endpoint in import and read, and modified docs of how to import

* fix: set the other parameters for private link and endpoint to avoid detecting changes while terraform plan after import

* fix: added parameter region in state id for import and other func to avoid detecting unnecessary changes

* fix: changed the wrong order for private link and endpoint service id in private link service

* docs: updated terraform import example for privatelink endpoint

Co-authored-by: Edgar López <[email protected]>
  • Loading branch information
coderGo93 and Edgar López authored Jan 26, 2021
1 parent b44afaa commit 785dee1
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package mongodbatlas
import (
"context"
"fmt"
"net/url"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/spf13/cast"
Expand Down Expand Up @@ -74,8 +75,9 @@ func dataSourceMongoDBAtlasPrivateEndpointServiceLinkRead(d *schema.ResourceData
privateLinkID := d.Get("private_link_id").(string)
endpointServiceID := d.Get("endpoint_service_id").(string)
providerName := d.Get("provider_name").(string)
encodedEndpointID := url.PathEscape(endpointServiceID)

serviceEndpoint, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, endpointServiceID, privateLinkID)
serviceEndpoint, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, privateLinkID, encodedEndpointID)
if err != nil {
return fmt.Errorf(errorServiceEndpointRead, endpointServiceID, err)
}
Expand All @@ -95,7 +97,7 @@ func dataSourceMongoDBAtlasPrivateEndpointServiceLinkRead(d *schema.ResourceData
d.SetId(encodeStateID(map[string]string{
"project_id": projectID,
"private_link_id": privateLinkID,
"endpoint_service_id": serviceEndpoint.ID,
"endpoint_service_id": endpointServiceID,
"provider_name": providerName,
}))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestAccDataSourceMongoDBAtlasPrivateLinkEndpointServiceAWS_basic(t *testing
securityGroupID := os.Getenv("AWS_SECURITY_GROUP_ID")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); checkAwsEnv(t); checkPeeringEnvAWS(t) },
PreCheck: func() { testAccPreCheck(t); checkAwsEnv(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Expand Down Expand Up @@ -66,8 +66,8 @@ func testAccMongoDBAtlasPrivateLinkEndpointServiceDataSourceConfig(awsAccessKey,
resource "mongodbatlas_privatelink_endpoint_service" "test" {
project_id = mongodbatlas_privatelink_endpoint.test.project_id
private_link_id = aws_vpc_endpoint.ptfe_service.id
endpoint_service_id = mongodbatlas_privatelink_endpoint.test.private_link_id
endpoint_service_id = aws_vpc_endpoint.ptfe_service.id
private_link_id = mongodbatlas_privatelink_endpoint.test.private_link_id
provider_name = "%[4]s"
}
Expand Down
20 changes: 17 additions & 3 deletions mongodbatlas/resource_mongodbatlas_private_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ func resourceMongoDBAtlasPrivateEndpointRead(d *schema.ResourceData, meta interf
ids := decodeStateID(d.Id())
projectID := ids["project_id"]
privateLinkID := ids["private_link_id"]
providerName := ids["provider_name"]
region := ids["region"]

privateEndpoint, _, err := conn.PrivateEndpointsDeprecated.Get(context.Background(), projectID, privateLinkID)
if err != nil {
Expand All @@ -144,6 +146,14 @@ func resourceMongoDBAtlasPrivateEndpointRead(d *schema.ResourceData, meta interf
return fmt.Errorf(errorPrivateEndpointsSetting, "status", privateLinkID, err)
}

if err := d.Set("provider_name", providerName); err != nil {
return fmt.Errorf(errorPrivateEndpointsSetting, "provider_name", privateLinkID, err)
}

if err := d.Set("region", region); err != nil {
return fmt.Errorf(errorPrivateEndpointsSetting, "provider_name", privateLinkID, err)
}

return nil
}

Expand Down Expand Up @@ -185,13 +195,15 @@ func resourceMongoDBAtlasPrivateEndpointDelete(d *schema.ResourceData, meta inte
func resourceMongoDBAtlasPrivateEndpointImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
conn := meta.(*matlas.Client)

parts := strings.SplitN(d.Id(), "-", 2)
if len(parts) != 2 {
return nil, errors.New("import format error: to import a MongoDB Private Endpoint, use the format {project_id}-{private_link_id}")
parts := strings.Split(d.Id(), "-")
if len(parts) != 6 {
return nil, errors.New("import format error: to import a MongoDB Private Endpoint, use the format {project_id}-{private_link_id}-{provider_name}-{region} ")
}

projectID := parts[0]
privateLinkID := parts[1]
providerName := parts[2]
region := fmt.Sprintf("%s-%s-%s", parts[3], parts[4], parts[5])

privateEndpoint, _, err := conn.PrivateEndpointsDeprecated.Get(context.Background(), projectID, privateLinkID)
if err != nil {
Expand All @@ -205,6 +217,8 @@ func resourceMongoDBAtlasPrivateEndpointImportState(d *schema.ResourceData, meta
d.SetId(encodeStateID(map[string]string{
"private_link_id": privateEndpoint.ID,
"project_id": projectID,
"provider_name": providerName,
"region": region,
}))

return []*schema.ResourceData{d}, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ func resourceMongoDBAtlasPrivateEndpointInterfaceLinkRead(d *schema.ResourceData
return fmt.Errorf(errorInterfaceEndpointSetting, "connection_status", interfaceEndpointID, err)
}

if err := d.Set("private_link_id", privateLinkID); err != nil {
return fmt.Errorf(errorPrivateEndpointsSetting, "private_link_id", privateLinkID, err)
}

if err := d.Set("interface_endpoint_id", interfaceEndpointID); err != nil {
return fmt.Errorf(errorPrivateEndpointsSetting, "interface_endpoint_id", privateLinkID, err)
}

return nil
}

Expand Down
24 changes: 20 additions & 4 deletions mongodbatlas/resource_mongodbatlas_privatelink_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,11 @@ func resourceMongoDBAtlasPrivateLinkEndpointCreate(d *schema.ResourceData, meta
conn := meta.(*matlas.Client)
projectID := d.Get("project_id").(string)
providerName := d.Get("provider_name").(string)
region := d.Get("region").(string)

request := &matlas.PrivateEndpointConnection{
ProviderName: providerName,
Region: d.Get("region").(string),
Region: region,
}

privateEndpointConn, _, err := conn.PrivateEndpoints.Create(context.Background(), projectID, request)
Expand All @@ -123,6 +124,7 @@ func resourceMongoDBAtlasPrivateLinkEndpointCreate(d *schema.ResourceData, meta
"private_link_id": privateEndpointConn.ID,
"project_id": projectID,
"provider_name": providerName,
"region": region,
}))

return resourceMongoDBAtlasPrivateLinkEndpointRead(d, meta)
Expand All @@ -135,6 +137,7 @@ func resourceMongoDBAtlasPrivateLinkEndpointRead(d *schema.ResourceData, meta in
projectID := ids["project_id"]
privateLinkID := ids["private_link_id"]
providerName := ids["provider_name"]
region := ids["region"]

privateEndpoint, _, err := conn.PrivateEndpoints.Get(context.Background(), projectID, providerName, privateLinkID)
if err != nil {
Expand Down Expand Up @@ -173,6 +176,14 @@ func resourceMongoDBAtlasPrivateLinkEndpointRead(d *schema.ResourceData, meta in
return fmt.Errorf(errorPrivateLinkEndpointsSetting, "status", privateLinkID, err)
}

if err := d.Set("provider_name", providerName); err != nil {
return fmt.Errorf(errorPrivateLinkEndpointsSetting, "provider_name", privateLinkID, err)
}

if err := d.Set("region", region); err != nil {
return fmt.Errorf(errorPrivateLinkEndpointsSetting, "region", privateLinkID, err)
}

return nil
}

Expand Down Expand Up @@ -215,14 +226,18 @@ func resourceMongoDBAtlasPrivateLinkEndpointDelete(d *schema.ResourceData, meta
func resourceMongoDBAtlasPrivateLinkEndpointImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
conn := meta.(*matlas.Client)

parts := strings.SplitN(d.Id(), "-", 3)
if len(parts) != 3 {
return nil, errors.New("import format error: to import a MongoDB Private Endpoint, use the format {project_id}-{private_link_id}-{provider_name}")
parts := strings.Split(d.Id(), "-")
if len(parts) != 6 && len(parts) != 4 {
return nil, errors.New("import format error: to import a MongoDB Private Endpoint, use the format {project_id}-{private_link_id}-{provider_name}-{region}")
}

projectID := parts[0]
privateLinkID := parts[1]
providerName := parts[2]
region := parts[3] // If region it's azure or Atlas format like US_EAST_1
if len(parts) == 6 {
region = fmt.Sprintf("%s-%s-%s", parts[3], parts[4], parts[5])
}

privateEndpoint, _, err := conn.PrivateEndpoints.Get(context.Background(), projectID, providerName, privateLinkID)
if err != nil {
Expand All @@ -237,6 +252,7 @@ func resourceMongoDBAtlasPrivateLinkEndpointImportState(d *schema.ResourceData,
"private_link_id": privateEndpoint.ID,
"project_id": projectID,
"provider_name": providerName,
"region": region,
}))

return []*schema.ResourceData{d}, nil
Expand Down
22 changes: 13 additions & 9 deletions mongodbatlas/resource_mongodbatlas_privatelink_endpoint_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ func resourceMongoDBAtlasPrivateEndpointServiceLinkCreate(d *schema.ResourceData
endpointServiceID := d.Get("endpoint_service_id").(string)

request := &matlas.InterfaceEndpointConnection{
ID: privateLinkID,
ID: endpointServiceID,
PrivateEndpointIPAddress: d.Get("private_endpoint_ip_address").(string),
}

_, _, err := conn.PrivateEndpoints.AddOnePrivateEndpoint(context.Background(), projectID, providerName, endpointServiceID, request)
_, _, err := conn.PrivateEndpoints.AddOnePrivateEndpoint(context.Background(), projectID, providerName, privateLinkID, request)
if err != nil {
return fmt.Errorf(errorServiceEndpointAdd, providerName, privateLinkID, err)
}
Expand Down Expand Up @@ -136,9 +136,9 @@ func resourceMongoDBAtlasPrivateEndpointServiceLinkRead(d *schema.ResourceData,
privateLinkID := ids["private_link_id"]
endpointServiceID := ids["endpoint_service_id"]
providerName := ids["provider_name"]
encodedPrivateLinkID := url.PathEscape(privateLinkID)
encodedEndpointID := url.PathEscape(endpointServiceID)

privateEndpoint, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, endpointServiceID, encodedPrivateLinkID)
privateEndpoint, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, privateLinkID, encodedEndpointID)
if err != nil {
return fmt.Errorf(errorServiceEndpointRead, endpointServiceID, err)
}
Expand Down Expand Up @@ -175,6 +175,10 @@ func resourceMongoDBAtlasPrivateEndpointServiceLinkRead(d *schema.ResourceData,
return fmt.Errorf(errorEndpointSetting, "endpoint_service_id", endpointServiceID, err)
}

if err := d.Set("private_link_id", privateLinkID); err != nil {
return fmt.Errorf(errorEndpointSetting, "private_link_id", endpointServiceID, err)
}

return nil
}

Expand All @@ -186,10 +190,10 @@ func resourceMongoDBAtlasPrivateEndpointServiceLinkDelete(d *schema.ResourceData
privateLinkID := ids["private_link_id"]
endpointServiceID := ids["endpoint_service_id"]
providerName := ids["provider_name"]
encodedPrivateLinkID := url.PathEscape(privateLinkID)
encodedEndpointID := url.PathEscape(endpointServiceID)

if endpointServiceID != "" {
_, err := conn.PrivateEndpoints.DeleteOnePrivateEndpoint(context.Background(), projectID, providerName, endpointServiceID, encodedPrivateLinkID)
_, err := conn.PrivateEndpoints.DeleteOnePrivateEndpoint(context.Background(), projectID, providerName, privateLinkID, encodedEndpointID)
if err != nil {
return fmt.Errorf(errorEndpointDelete, endpointServiceID, err)
}
Expand Down Expand Up @@ -225,9 +229,9 @@ func resourceMongoDBAtlasPrivateEndpointServiceLinkImportState(d *schema.Resourc
privateLinkID := parts[1]
endpointServiceID := parts[2]
providerName := parts[3]
encodedPrivateLinkID := url.PathEscape(privateLinkID)
encodedEndpointID := url.PathEscape(endpointServiceID)

_, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, endpointServiceID, encodedPrivateLinkID)
_, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, privateLinkID, encodedEndpointID)
if err != nil {
return nil, fmt.Errorf(errorServiceEndpointRead, endpointServiceID, err)
}
Expand Down Expand Up @@ -260,7 +264,7 @@ func resourceMongoDBAtlasPrivateEndpointServiceLinkImportState(d *schema.Resourc

func resourceServiceEndpointRefreshFunc(client *matlas.Client, projectID, providerName, privateLinkID, endpointServiceID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
i, resp, err := client.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, endpointServiceID, privateLinkID)
i, resp, err := client.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), projectID, providerName, privateLinkID, endpointServiceID)
if err != nil {
if resp != nil && resp.StatusCode == 404 {
return "", "DELETED", nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package mongodbatlas
import (
"context"
"fmt"
"net/url"
"os"
"testing"

Expand All @@ -28,7 +29,7 @@ func TestAccResourceMongoDBAtlasPrivateLinkEndpointServiceAWS_Complete(t *testin
)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); checkAwsEnv(t); checkPeeringEnvAWS(t) },
PreCheck: func() { testAccPreCheck(t); checkAwsEnv(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckMongoDBAtlasPrivateLinkEndpointServiceDestroy,
Steps: []resource.TestStep{
Expand Down Expand Up @@ -117,7 +118,7 @@ func testAccCheckMongoDBAtlasPrivateLinkEndpointServiceExists(resourceName strin

ids := decodeStateID(rs.Primary.ID)

_, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), ids["project_id"], ids["provider_name"], ids["endpoint_service_id"], ids["private_link_id"])
_, _, err := conn.PrivateEndpoints.GetOnePrivateEndpoint(context.Background(), ids["project_id"], ids["provider_name"], ids["private_link_id"], url.QueryEscape(ids["endpoint_service_id"]))
if err == nil {
return nil
}
Expand Down Expand Up @@ -169,8 +170,8 @@ func testAccMongoDBAtlasPrivateLinkEndpointServiceConfigCompleteAWS(awsAccessKey
resource "mongodbatlas_privatelink_endpoint_service" "test" {
project_id = mongodbatlas_privatelink_endpoint.test.project_id
private_link_id = aws_vpc_endpoint.ptfe_service.id
endpoint_service_id = mongodbatlas_privatelink_endpoint.test.private_link_id
endpoint_service_id = aws_vpc_endpoint.ptfe_service.id
private_link_id = mongodbatlas_privatelink_endpoint.test.private_link_id
provider_name = "%[4]s"
}
`, awsAccessKey, awsSecretKey, projectID, providerName, region, vpcID, subnetID, securityGroupID)
Expand Down
20 changes: 9 additions & 11 deletions mongodbatlas/resource_mongodbatlas_privatelink_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,10 @@ func TestAccResourceMongoDBAtlasPrivateLinkEndpointAWS_import(t *testing.T) {
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: testAccCheckMongoDBAtlasPrivateLinkEndpointImportStateIDFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"provider_name", "region"},
ResourceName: resourceName,
ImportStateIdFunc: testAccCheckMongoDBAtlasPrivateLinkEndpointImportStateIDFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
},
},
})
Expand Down Expand Up @@ -134,11 +133,10 @@ func TestAccResourceMongoDBAtlasPrivateLinkEndpointAzure_import(t *testing.T) {
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: testAccCheckMongoDBAtlasPrivateLinkEndpointImportStateIDFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"provider_name", "region"},
ResourceName: resourceName,
ImportStateIdFunc: testAccCheckMongoDBAtlasPrivateLinkEndpointImportStateIDFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
},
},
})
Expand All @@ -153,7 +151,7 @@ func testAccCheckMongoDBAtlasPrivateLinkEndpointImportStateIDFunc(resourceName s

ids := decodeStateID(rs.Primary.ID)

return fmt.Sprintf("%s-%s-%s", ids["project_id"], ids["private_link_id"], ids["provider_name"]), nil
return fmt.Sprintf("%s-%s-%s-%s", ids["project_id"], ids["private_link_id"], ids["provider_name"], ids["region"]), nil
}
}

Expand Down
7 changes: 4 additions & 3 deletions website/docs/d/privatelink_endpoint_service.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ resource "aws_vpc_endpoint" "ptfe_service" {
resource "mongodbatlas_privatelink_endpoint_service" "test" {
project_id = "${mongodbatlas_privatelink_endpoint.test.project_id}"
private_link_id = "${mongodbatlas_privatelink_endpoint.test.private_link_id}"
interface_endpoint_id = "${aws_vpc_endpoint.ptfe_service.id}"
endpoint_service_id = "${aws_vpc_endpoint.ptfe_service.id}"
provider_name ="AWS"
}
data "mongodbatlas_privatelink_endpoint_service" "test" {
Expand All @@ -45,8 +46,8 @@ data "mongodbatlas_privatelink_endpoint_service" "test" {
## Argument Reference

* `project_id` - (Required) Unique identifier for the project.
* `private_link_id` - (Required) Unique identifier of the `AWS` or `AZURE` PrivateLink connection.
* `endpoint_service_id` - (Required) Unique identifier of the private endpoint service for which you want to create a private endpoint service.
* `private_link_id` - (Required) Unique identifier of the private endpoint service for which you want to retrieve a private endpoint.
* `endpoint_service_id` - (Required) Unique identifier of the `AWS` or `AZURE` resource.
* `provider_name` - (Required) Cloud provider for which you want to create a private endpoint. Atlas accepts `AWS` or `AZURE`.

## Attributes Reference
Expand Down
2 changes: 1 addition & 1 deletion website/docs/guides/0.8.0-upgrade-guide.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ In order to transition from the deprecated resources to the new without disablin
3) Then [import](https://www.terraform.io/docs/commands/import.html) the privatelink information into the new resources, e.g:

```hcl
terraform import mongodbatlas_privatelink_endpoint.test {project_id}-{private_link_id}-{provider_name}
terraform import mongodbatlas_privatelink_endpoint.test {project_id}-{private_link_id}-{provider_name}-{region}
terraform import mongodbatlas_privatelink_endpoint_service.test {project_id}--{private_link_id}--{endpoint_service_id}--{provider_name}
```
Expand Down
4 changes: 2 additions & 2 deletions website/docs/r/private_endpoint.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ In addition to all arguments above, the following attributes are exported:
* `DELETING` The AWS PrivateLink connection is being deleted.

## Import
Private Endpoint Connection can be imported using project ID and username, in the format `{project_id}-{private_link_id}`, e.g.
Private Endpoint Connection can be imported using project ID and private link ID, provider name and region, in the format `{project_id}-{private_link_id}-{provider_name}-{region}`, e.g.

```
$ terraform import mongodbatlas_private_endpoint.test 1112222b3bf99403840e8934-3242342343112
$ terraform import mongodbatlas_private_endpoint.test 1112222b3bf99403840e8934-3242342343112-AWS-us-east-2
```

See detailed information for arguments and attributes: [MongoDB API Private Endpoint Connection](https://docs.atlas.mongodb.com/reference/api/private-endpoint-create-one-private-endpoint-connection/)
4 changes: 2 additions & 2 deletions website/docs/r/privatelink_endpoint.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ In addition to all arguments above, the following attributes are exported:
* `DELETING` The Private Link service is being deleted.

## Import
Private Endpoint Service can be imported using project ID and username, in the format `{project_id}-{private_link_id}-{provider_name}`, e.g.
Private Endpoint Service can be imported using project ID, private link ID, provider name and region, in the format `{project_id}-{private_link_id}-{provider_name}-{region}`, e.g.

```
$ terraform import mongodbatlas_privatelink_endpoint.test 1112222b3bf99403840e8934-3242342343112-AWS
$ terraform import mongodbatlas_privatelink_endpoint.test 1112222b3bf99403840e8934-3242342343112-AWS-us-east-1
```

See detailed information for arguments and attributes: [MongoDB API Private Endpoint Service](https://docs.atlas.mongodb.com/reference/api/private-endpoints-service-create-one//)
Loading

0 comments on commit 785dee1

Please sign in to comment.