diff --git a/cfn-resources/private-endpoint-aws/cmd/resource/model.go b/cfn-resources/private-endpoint-aws/cmd/resource/model.go
index bb6853444..d289f496e 100644
--- a/cfn-resources/private-endpoint-aws/cmd/resource/model.go
+++ b/cfn-resources/private-endpoint-aws/cmd/resource/model.go
@@ -9,6 +9,8 @@ type Model struct {
EndpointServiceId *string `json:",omitempty"`
Id *string `json:",omitempty"`
EnforceConnectionSuccess *bool `json:",omitempty"`
+ InterfaceEndpointId *string `json:",omitempty"`
+ DeleteRequested *bool `json:",omitempty"`
ConnectionStatus *string `json:",omitempty"`
ErrorMessage *string `json:",omitempty"`
}
diff --git a/cfn-resources/private-endpoint-aws/cmd/resource/resource.go b/cfn-resources/private-endpoint-aws/cmd/resource/resource.go
index 9da66335a..436981006 100644
--- a/cfn-resources/private-endpoint-aws/cmd/resource/resource.go
+++ b/cfn-resources/private-endpoint-aws/cmd/resource/resource.go
@@ -21,7 +21,7 @@ import (
"net/http"
"strings"
- admin20231115014 "go.mongodb.org/atlas-sdk/v20231115014/admin"
+ "go.mongodb.org/atlas-sdk/v20250312012/admin"
"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/handler"
"github.com/aws/aws-sdk-go-v2/aws"
@@ -92,11 +92,13 @@ func Create(req handler.Request, prevModel *Model, currentModel *Model) (handler
*privateEndpoint.ConnectionStatus == Rejected {
return handler.ProgressEvent{
OperationStatus: handler.Failed,
- Message: fmt.Sprintf("Connection was Rejected : %s", *privateEndpoint.ErrorMessage),
+ Message: fmt.Sprintf("Connection was Rejected: %s", *privateEndpoint.ErrorMessage),
ResourceModel: currentModel,
}, nil
}
+ currentModel.completeByAtlasModel(*privateEndpoint)
+
return handler.ProgressEvent{
OperationStatus: handler.Success,
Message: "Create Success",
@@ -115,17 +117,17 @@ func Create(req handler.Request, prevModel *Model, currentModel *Model) (handler
}}, nil
}
- endpointRequest := admin20231115014.CreateEndpointRequest{
+ endpointRequest := admin.CreateEndpointRequest{
Id: currentModel.Id,
}
- privateEndpointRequest := client.Atlas20231115014.PrivateEndpointServicesApi.CreatePrivateEndpoint(context.Background(), *currentModel.ProjectId,
+ privateEndpointRequest := client.AtlasSDK.PrivateEndpointServicesApi.CreatePrivateEndpoint(context.Background(), *currentModel.ProjectId,
CloudProvider, *currentModel.EndpointServiceId, &endpointRequest)
_, response, err := privateEndpointRequest.Execute()
defer response.Body.Close()
if err != nil {
- if response.StatusCode == http.StatusConflict {
+ if util.StatusConflict(response) {
return progress_events.GetFailedEventByCode(
fmt.Sprintf("error creating Serverless Private Endpoint %s", err.Error()),
string(types.HandlerErrorCodeAlreadyExists),
@@ -146,8 +148,8 @@ func Create(req handler.Request, prevModel *Model, currentModel *Model) (handler
}}, nil
}
-func getPrivateEndpoint(client *util.MongoDBClient, model *Model) (*admin20231115014.PrivateLinkEndpoint, *http.Response, error) {
- privateEndpointRequest := client.Atlas20231115014.PrivateEndpointServicesApi.GetPrivateEndpoint(context.Background(), *model.ProjectId,
+func getPrivateEndpoint(client *util.MongoDBClient, model *Model) (*admin.PrivateLinkEndpoint, *http.Response, error) {
+ privateEndpointRequest := client.AtlasSDK.PrivateEndpointServicesApi.GetPrivateEndpoint(context.Background(), *model.ProjectId,
CloudProvider, *model.Id, *model.EndpointServiceId)
privateEndpoint, response, err := privateEndpointRequest.Execute()
@@ -184,9 +186,11 @@ func Read(req handler.Request, prevModel *Model, currentModel *Model) (handler.P
}, nil
}
-func (m *Model) completeByAtlasModel(privateEndpoint admin20231115014.PrivateLinkEndpoint) {
- m.ErrorMessage = privateEndpoint.ErrorMessage
+func (m *Model) completeByAtlasModel(privateEndpoint admin.PrivateLinkEndpoint) {
+ m.InterfaceEndpointId = privateEndpoint.InterfaceEndpointId
+ m.DeleteRequested = privateEndpoint.DeleteRequested
m.ConnectionStatus = privateEndpoint.ConnectionStatus
+ m.ErrorMessage = privateEndpoint.ErrorMessage
}
// Update handles the Update event from the Cloudformation service.
@@ -215,10 +219,10 @@ func Delete(req handler.Request, prevModel *Model, currentModel *Model) (handler
_, response, peError := getPrivateEndpoint(client, currentModel)
defer response.Body.Close()
if peError != nil {
- if response.StatusCode == http.StatusNotFound {
+ if util.StatusNotFound(response) {
return handler.ProgressEvent{
OperationStatus: handler.Success,
- Message: "Create Success",
+ Message: "Delete Success",
}, nil
}
return progress_events.GetFailedEventByResponse("Error validating Private Endpoint deletion progress", response), nil
@@ -226,26 +230,28 @@ func Delete(req handler.Request, prevModel *Model, currentModel *Model) (handler
return handler.ProgressEvent{
OperationStatus: handler.InProgress,
- Message: "Create in progress",
+ Message: "Delete in progress",
CallbackDelaySeconds: 20,
CallbackContext: map[string]interface{}{
"state": "deleting",
}}, nil
}
- privateEndpointRequest := client.Atlas20231115014.PrivateEndpointServicesApi.DeletePrivateEndpoint(context.Background(), *currentModel.ProjectId,
+ privateEndpointRequest := client.AtlasSDK.PrivateEndpointServicesApi.DeletePrivateEndpoint(context.Background(), *currentModel.ProjectId,
CloudProvider, *currentModel.Id, *currentModel.EndpointServiceId)
- _, response, err := privateEndpointRequest.Execute()
- defer response.Body.Close()
+ response, err := privateEndpointRequest.Execute()
+ if response != nil && response.Body != nil {
+ defer response.Body.Close()
+ }
if err != nil {
- return progress_events.GetFailedEventByResponse(fmt.Sprintf("error creating Serverless Private Endpoint %s",
+ return progress_events.GetFailedEventByResponse(fmt.Sprintf("error deleting Private Endpoint: %s",
err.Error()), response),
nil
}
return handler.ProgressEvent{
OperationStatus: handler.InProgress,
- Message: "Create in progress",
+ Message: "Delete in progress",
CallbackDelaySeconds: 20,
ResourceModel: currentModel,
CallbackContext: map[string]interface{}{
diff --git a/cfn-resources/private-endpoint-aws/docs/README.md b/cfn-resources/private-endpoint-aws/docs/README.md
index 7e7913d23..11e0658dd 100644
--- a/cfn-resources/private-endpoint-aws/docs/README.md
+++ b/cfn-resources/private-endpoint-aws/docs/README.md
@@ -17,8 +17,6 @@ To declare this entity in your AWS CloudFormation template, use the following sy
"EndpointServiceId" : String,
"Id" : String,
"EnforceConnectionSuccess" : Boolean,
- "ConnectionStatus" : String,
- "ErrorMessage" : String
}
}
@@ -33,8 +31,6 @@ Properties:
EndpointServiceId: String
Id: String
EnforceConnectionSuccess: Boolean
- ConnectionStatus: String
- ErrorMessage: String
## Properties
@@ -73,7 +69,7 @@ _Update requires_: [Replacement](https://docs.aws.amazon.com/AWSCloudFormation/l
Unique string that identifies the private endpoint. for AWS is the VPC endpoint ID, example: vpce-xxxxxxxx
-_Required_: No
+_Required_: Yes
_Type_: String
@@ -89,23 +85,27 @@ _Type_: Boolean
_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
-#### ConnectionStatus
+## Return Values
-State of the Amazon Web Service PrivateLink connection when MongoDB Cloud received this request.
+### Fn::GetAtt
-_Required_: No
+The `Fn::GetAtt` intrinsic function returns a value for a specified attribute of this type. The following are the available attributes and sample return values.
-_Type_: String
+For more information about using the `Fn::GetAtt` intrinsic function, see [Fn::GetAtt](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html).
-_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
+#### InterfaceEndpointId
-#### ErrorMessage
+Unique identifier of the AWS VPC interface endpoint (e.g., vpce-0d00c26273372c6ef).
-Error message returned when requesting private connection resource. The resource returns null if the request succeeded.
+#### DeleteRequested
-_Required_: No
+Indicates if Atlas received a request to remove the interface endpoint from the private endpoint connection.
-_Type_: String
+#### ConnectionStatus
-_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
+State of the Amazon Web Service PrivateLink connection when MongoDB Cloud received this request.
+
+#### ErrorMessage
+
+Error message returned when requesting private connection resource. The resource returns null if the request succeeded.
diff --git a/cfn-resources/private-endpoint-aws/mongodb-atlas-privateendpointaws.json b/cfn-resources/private-endpoint-aws/mongodb-atlas-privateendpointaws.json
index 10f394953..5bf030164 100644
--- a/cfn-resources/private-endpoint-aws/mongodb-atlas-privateendpointaws.json
+++ b/cfn-resources/private-endpoint-aws/mongodb-atlas-privateendpointaws.json
@@ -8,7 +8,8 @@
},
"required": [
"ProjectId",
- "EndpointServiceId"
+ "EndpointServiceId",
+ "Id"
],
"properties": {
"Profile": {
@@ -32,6 +33,14 @@
"description": "If this proper is set to TRUE, the cloud formation resource will return success Only if the private connection is Succeeded",
"type": "boolean"
},
+ "InterfaceEndpointId": {
+ "description": "Unique identifier of the AWS VPC interface endpoint (e.g., vpce-0d00c26273372c6ef).",
+ "type": "string"
+ },
+ "DeleteRequested": {
+ "description": "Indicates if Atlas received a request to remove the interface endpoint from the private endpoint connection.",
+ "type": "boolean"
+ },
"ConnectionStatus": {
"description": "State of the Amazon Web Service PrivateLink connection when MongoDB Cloud received this request.",
"type": "string"
@@ -54,6 +63,12 @@
"/properties/Profile",
"/properties/Id"
],
+ "readOnlyProperties": [
+ "/properties/InterfaceEndpointId",
+ "/properties/DeleteRequested",
+ "/properties/ConnectionStatus",
+ "/properties/ErrorMessage"
+ ],
"handlers": {
"create": {
"permissions": [
diff --git a/examples/private-endpoint-aws/README.md b/examples/private-endpoint-aws/README.md
new file mode 100644
index 000000000..399be6bad
--- /dev/null
+++ b/examples/private-endpoint-aws/README.md
@@ -0,0 +1,21 @@
+# How to create a MongoDB::Atlas::PrivateEndpointAWS
+
+## Step 1: Activate the PrivateEndpointAWS resource in CloudFormation
+ Step a: Create Role using [execution-role.yaml](https://github.com/mongodb/mongodbatlas-cloudformation-resources/blob/master/examples/execution-role.yaml) in CFN resources folder.
+
+ Step b: Search for MongoDB::Atlas::PrivateEndpointAWS resource.
+
+ (CloudFormation > Public extensions > choose 'Third party' > Search with " Execution name prefix = MongoDB " )
+
+ Step c: Select and activate
+ Enter the RoleArn that is created in step 1.
+
+ Your PrivateEndpointAWS Resource is ready to use.
+
+## Step 2: Create template using [private-endpoint-aws.json](private-endpoint-aws.json)
+ Note: Make sure you are providing appropriate values for:
+ 1. MongoDBAtlasProjectId
+ 2. AtlasPrivateEndpointServiceId (get from: `atlas privateEndpoints aws list --projectId `)
+ 3. AWSVPCEndpointId (format: vpce-xxxxxxxxx)
+ 4. Profile (optional)
+ 5. EnforceConnectionSuccess (optional)
\ No newline at end of file
diff --git a/examples/private-endpoint-aws/private-endpoint-aws.json b/examples/private-endpoint-aws/private-endpoint-aws.json
new file mode 100644
index 000000000..d814eb9ad
--- /dev/null
+++ b/examples/private-endpoint-aws/private-endpoint-aws.json
@@ -0,0 +1,87 @@
+{
+ "AWSTemplateFormatVersion": "2010-09-09",
+ "Description": "Test template for MongoDB::Atlas::PrivateEndpointAWS resource. Links an existing AWS VPC Endpoint to an existing Atlas Private Endpoint Service.",
+ "Parameters": {
+ "Profile": {
+ "Type": "String",
+ "Description": "Atlas Profile name for credential management. See profile-secret.yaml for setup instructions.",
+ "Default": "default"
+ },
+ "MongoDBAtlasProjectId": {
+ "Type": "String",
+ "Description": "Unique 24-hexadecimal digit string that identifies your MongoDB Atlas project.",
+ "AllowedPattern": "^([a-f0-9]{24})$",
+ "ConstraintDescription": "Must be a valid 24-character hexadecimal MongoDB Atlas project ID."
+ },
+ "AtlasPrivateEndpointServiceId": {
+ "Type": "String",
+ "Description": "The Atlas Private Endpoint Service ID (24-character hexadecimal). Get this from MongoDB::Atlas::PrivateEndpointService.Id or Atlas CLI.",
+ "AllowedPattern": "^([a-f0-9]{24})$",
+ "ConstraintDescription": "Must be a valid 24-character hexadecimal Atlas Private Endpoint Service ID."
+ },
+ "AWSVPCEndpointId": {
+ "Type": "String",
+ "Description": "The AWS VPC Endpoint ID that you want to link to Atlas (e.g., vpce-0123456789abcdef0).",
+ "AllowedPattern": "^vpce-[a-z0-9]{8,17}$",
+ "ConstraintDescription": "Must be a valid AWS VPC Endpoint ID starting with 'vpce-'."
+ },
+ "EnforceConnectionSuccess": {
+ "Type": "String",
+ "Description": "If true, CloudFormation will fail if the connection is REJECTED. If false, it succeeds even if REJECTED.",
+ "Default": "true",
+ "AllowedValues": ["true", "false"]
+ }
+ },
+ "Resources": {
+ "AtlasPrivateEndpointConnection": {
+ "Type": "MongoDB::Atlas::PrivateEndpointAWS",
+ "Properties": {
+ "ProjectId": {
+ "Ref": "MongoDBAtlasProjectId"
+ },
+ "EndpointServiceId": {
+ "Ref": "AtlasPrivateEndpointServiceId"
+ },
+ "Id": {
+ "Ref": "AWSVPCEndpointId"
+ },
+ "Profile": {
+ "Ref": "Profile"
+ },
+ "EnforceConnectionSuccess": {
+ "Ref": "EnforceConnectionSuccess"
+ }
+ }
+ }
+ },
+ "Outputs": {
+ "ConnectionStatus": {
+ "Description": "Status of the AWS PrivateLink connection. Returns one of: NONE, PENDING_ACCEPTANCE, PENDING, AVAILABLE, REJECTED, DELETING.",
+ "Value": {
+ "Fn::GetAtt": [
+ "AtlasPrivateEndpointConnection",
+ "ConnectionStatus"
+ ]
+ }
+ },
+ "InterfaceEndpointId": {
+ "Description": "Unique identifier of the interface endpoint.",
+ "Value": {
+ "Fn::GetAtt": [
+ "AtlasPrivateEndpointConnection",
+ "InterfaceEndpointId"
+ ]
+ }
+ },
+ "DeleteRequested": {
+ "Description": "Indicates if Atlas received a request to remove the interface endpoint from the private endpoint connection.",
+ "Value": {
+ "Fn::GetAtt": [
+ "AtlasPrivateEndpointConnection",
+ "DeleteRequested"
+ ]
+ }
+ }
+ }
+}
+