Skip to content

Commit fcb474a

Browse files
author
sivaram-mongodb
committed
feat: Add Org-Service-account ClooudFormation resource
1 parent 15e0b8a commit fcb474a

24 files changed

Lines changed: 1889 additions & 2 deletions

cfn-resources/cfn-testing-helper.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,14 @@ done
157157
echo "Step 4/4: cleaning up 'cfn test' inputs "
158158
SAM_LOG=$(mktemp)
159159
for resource in ${resources}; do
160-
cd "${res}"
160+
cd "${resource}"
161+
if [ -f ./test/cfn-test-delete-inputs.sh ]; then
161162
chmod +x ./test/cfn-test-delete-inputs.sh
162-
./test/cfn-test-delete-inputs.sh "${PROJECT_NAME}-${res}" && echo "resource:${res} inputs delete OK" || echo "resource:${res} input delete FAILED"
163+
./test/cfn-test-delete-inputs.sh "${PROJECT_NAME}-${resource}" && echo "resource:${resource} inputs delete OK" || echo "resource:${resource} input delete FAILED"
164+
else
165+
echo "resource:${resource} - delete script not found, skipping cleanup"
166+
fi
167+
cd -
163168
done
164169

165170
echo "Clean up project"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"artifact_type": "RESOURCE",
3+
"typeName": "MongoDB::Atlas::OrgServiceAccount",
4+
"language": "go",
5+
"runtime": "provided.al2",
6+
"entrypoint": "bootstrap",
7+
"testEntrypoint": "bootstrap",
8+
"settings": {
9+
"version": false,
10+
"subparser_name": null,
11+
"verbose": 0,
12+
"force": false,
13+
"type_name": null,
14+
"artifact_type": null,
15+
"endpoint_url": null,
16+
"region": null,
17+
"target_schemas": [],
18+
"profile": null,
19+
"import_path": "github.com/mongodb/mongodbatlas-cloudformation-resources/org-service-account",
20+
"protocolVersion": "2.0.0"
21+
},
22+
"canarySettings": {
23+
"contract_test_file_names": [
24+
"inputs_1.json"
25+
]
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.PHONY: build test clean debug
2+
tags=logging callback metrics scheduler
3+
cgo=0
4+
goos=linux
5+
goarch=amd64
6+
CFNREP_GIT_SHA?=$(shell git rev-parse HEAD)
7+
ldXflags=-s -w -X github.com/mongodb/mongodbatlas-cloudformation-resources/util.defaultLogLevel=info -X github.com/mongodb/mongodbatlas-cloudformation-resources/version.Version=${CFNREP_GIT_SHA}
8+
ldXflagsD=-X github.com/mongodb/mongodbatlas-cloudformation-resources/util.defaultLogLevel=debug -X github.com/mongodb/mongodbatlas-cloudformation-resources/version.Version=${CFNREP_GIT_SHA}
9+
10+
build:
11+
cfn generate
12+
env GOOS=$(goos) CGO_ENABLED=$(cgo) GOARCH=$(goarch) go build -ldflags="$(ldXflags)" -tags="$(tags)" -o bin/bootstrap cmd/main.go
13+
14+
debug:
15+
cfn generate
16+
env GOOS=$(goos) CGO_ENABLED=$(cgo) GOARCH=$(goarch) go build -ldflags="$(ldXflagsD)" -tags="$(tags)" -o bin/bootstrap cmd/main.go
17+
18+
test:
19+
cfn generate
20+
env GOOS=$(goos) go build -ldflags="-s -w" -tags="$(tags)" -o bin/bootstrap cmd/main.go
21+
22+
clean:
23+
rm -rf bin
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# MongoDB::Atlas::OrgServiceAccount
2+
3+
## Description
4+
5+
Resource for managing [Service Accounts](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/group/endpoint-service-accounts) for a MongoDB Atlas organization. Service accounts provide programmatic access to MongoDB Atlas resources and are used for automation, CI/CD pipelines, and service-to-service authentication.
6+
7+
## Requirements
8+
9+
To securely give CloudFormation access to your Atlas credentials, you must
10+
set up an [AWS Profile](/README.md#mongodb-atlas-api-keys-credential-management).
11+
12+
## Attributes and Parameters
13+
14+
See the [resource docs](docs/README.md).
15+
16+
## Cloudformation Examples
17+
18+
See the examples [CFN Template](/examples/org-service-account/README.md) for example resource.
19+

cfn-resources/org-service-account/cmd/main.go

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cfn-resources/org-service-account/cmd/resource/config.go

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2026 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package resource
16+
17+
import (
18+
"sort"
19+
20+
"go.mongodb.org/atlas-sdk/v20250312010/admin"
21+
22+
"github.com/mongodb/mongodbatlas-cloudformation-resources/util"
23+
)
24+
25+
func GetOrgServiceAccountModel(account *admin.OrgServiceAccount, currentModel *Model) *Model {
26+
model := new(Model)
27+
28+
if currentModel != nil {
29+
model = currentModel
30+
}
31+
if account != nil {
32+
if currentModel != nil {
33+
model.OrgId = currentModel.OrgId
34+
model.Profile = currentModel.Profile
35+
}
36+
model.Name = account.Name
37+
model.Description = account.Description
38+
if account.Roles != nil {
39+
roles := *account.Roles
40+
if currentModel != nil && currentModel.Roles != nil && len(currentModel.Roles) > 0 {
41+
model.Roles = currentModel.Roles
42+
} else {
43+
sort.Strings(roles)
44+
model.Roles = roles
45+
}
46+
}
47+
model.ClientId = account.ClientId
48+
model.CreatedAt = util.TimePtrToStringPtr(account.CreatedAt)
49+
50+
if account.Secrets != nil {
51+
model.Secrets = make([]Secret, len(*account.Secrets))
52+
for i, s := range *account.Secrets {
53+
createdAt := s.CreatedAt
54+
expiresAt := s.ExpiresAt
55+
model.Secrets[i] = Secret{
56+
Id: &s.Id,
57+
CreatedAt: util.TimePtrToStringPtr(&createdAt),
58+
ExpiresAt: util.TimePtrToStringPtr(&expiresAt),
59+
LastUsedAt: util.TimePtrToStringPtr(s.LastUsedAt),
60+
MaskedSecretValue: s.MaskedSecretValue,
61+
Secret: s.Secret,
62+
}
63+
}
64+
}
65+
}
66+
return model
67+
}
68+
69+
func NewOrgServiceAccountCreateReq(model *Model) *admin.OrgServiceAccountRequest {
70+
if model == nil {
71+
return nil
72+
}
73+
secretExpiresAfterHours := *model.SecretExpiresAfterHours
74+
roles := make([]string, len(model.Roles))
75+
copy(roles, model.Roles)
76+
sort.Strings(roles)
77+
return &admin.OrgServiceAccountRequest{
78+
Name: *model.Name,
79+
Description: *model.Description,
80+
Roles: roles,
81+
SecretExpiresAfterHours: secretExpiresAfterHours,
82+
}
83+
}
84+
85+
func NewOrgServiceAccountUpdateReq(model *Model) *admin.OrgServiceAccountUpdateRequest {
86+
if model == nil {
87+
return nil
88+
}
89+
var roles *[]string
90+
if len(model.Roles) > 0 {
91+
sortedRoles := make([]string, len(model.Roles))
92+
copy(sortedRoles, model.Roles)
93+
sort.Strings(sortedRoles)
94+
roles = &sortedRoles
95+
}
96+
return &admin.OrgServiceAccountUpdateRequest{
97+
Name: model.Name,
98+
Description: model.Description,
99+
Roles: roles,
100+
}
101+
}

0 commit comments

Comments
 (0)