From e8f2a3aef82a4796f155cc2d5b1bf3cec400bfb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:09:59 -0500 Subject: [PATCH 01/10] Chore(deps): Bump github.com/gruntwork-io/terratest (#978) Bumps [github.com/gruntwork-io/terratest](https://github.com/gruntwork-io/terratest) from 0.41.6 to 0.41.7. - [Release notes](https://github.com/gruntwork-io/terratest/releases) - [Commits](https://github.com/gruntwork-io/terratest/compare/v0.41.6...v0.41.7) --- updated-dependencies: - dependency-name: github.com/gruntwork-io/terratest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3abb452b6c..eb6e51b327 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/go-test/deep v1.1.0 - github.com/gruntwork-io/terratest v0.41.6 + github.com/gruntwork-io/terratest v0.41.7 github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/hashicorp/terraform-provider-google v1.20.1-0.20210625223728-379bcb41c06b github.com/mongodb-forks/digest v1.0.4 diff --git a/go.sum b/go.sum index b65fe9e9f7..234ae42a33 100644 --- a/go.sum +++ b/go.sum @@ -426,8 +426,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro= github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= -github.com/gruntwork-io/terratest v0.41.6 h1:BlZOu8GUzLEA2aODnyszCXSoF/jgo2AuVhk41vsqUQI= -github.com/gruntwork-io/terratest v0.41.6/go.mod h1:qH1xkPTTGx30XkMHw8jAVIbzqheSjIa5IyiTwSV2vKI= +github.com/gruntwork-io/terratest v0.41.7 h1:Vc0hb7ajWHutGA++gu/a9FSkuf+IuQuGDRymiWdrA04= +github.com/gruntwork-io/terratest v0.41.7/go.mod h1:qH1xkPTTGx30XkMHw8jAVIbzqheSjIa5IyiTwSV2vKI= github.com/hashicorp/aws-sdk-go-base v0.7.1 h1:7s/aR3hFn74tYPVihzDyZe7y/+BorN70rr9ZvpV3j3o= github.com/hashicorp/aws-sdk-go-base v0.7.1/go.mod h1:2fRjWDv3jJBeN6mVWFHV6hFTNeFBx2gpDLQaZNxUVAY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= From 71ee85fb573571673332132b3d6d9c6185548a78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:26:17 -0500 Subject: [PATCH 02/10] Chore(deps): Bump actions/stale from 6 to 7 (#977) Bumps [actions/stale](https://github.com/actions/stale) from 6 to 7. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index d5e9a50691..07a0f28062 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -9,7 +9,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v6 + - uses: actions/stale@v7 id: stale with: stale-issue-message: 'This issue has gone 30 days without any activity and meets the project’s definition of "stale". This will be auto-closed if there is no new activity over the next 30 days. If the issue is still relevant and active, you can simply comment with a "bump" to keep it open, or add the label "not_stale". Thanks for keeping our repository healthy!' From 7a57d21bd7f919994f7d3a7ff2728ff049717f60 Mon Sep 17 00:00:00 2001 From: martinstibbe <33664051+martinstibbe@users.noreply.github.com> Date: Thu, 22 Dec 2022 13:33:50 -0600 Subject: [PATCH 03/10] v1.7.0 Pre-Release (#980) * Delete mongodbatlas.erb (#962) * INTMDB-523: Rename exportJobID to exportID to match go client (#976) * Updated version of atlas api client used, renamed bucketID to exportJobID * Reverted changes to bucketID and updated exportJobID to exportID * INTMDB-521: AWS Secrets Manager to Auth into Terraform Atlas Provider (#975) * Add support for assume_role * Add documentation for assume_role feature * Add AWS parameters Env vars * Update index.html.markdown * Doc clean up * typo * Add regional behavior to endpoint sts client * Add sts_endpoint parameter * Update website/docs/index.html.markdown * formatting * formatting2 * Removed commented code Co-authored-by: Zuhair Ahmed * Update .github_changelog_generator Co-authored-by: Dosty Everts Co-authored-by: Zuhair Ahmed --- .github_changelog_generator | 4 +- go.mod | 2 +- go.sum | 2 + mongodbatlas/config.go | 1 + ...batlas_cloud_backup_snapshot_export_job.go | 4 +- mongodbatlas/provider.go | 297 +++++++++++++++++- ...batlas_cloud_backup_snapshot_export_job.go | 12 +- website/docs/index.html.markdown | 31 +- website/mongodbatlas.erb | 243 -------------- 9 files changed, 340 insertions(+), 256 deletions(-) delete mode 100644 website/mongodbatlas.erb diff --git a/.github_changelog_generator b/.github_changelog_generator index 0492113c4c..29056cc9e7 100644 --- a/.github_changelog_generator +++ b/.github_changelog_generator @@ -1,4 +1,4 @@ -future-release=v1.6.1 -since-tag=v1.6.0 +future-release=v1.7.0 +since-tag=v1.6.1 date-format=%B %d, %Y base=CHANGELOG.md diff --git a/go.mod b/go.mod index eb6e51b327..554e240f7e 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/mwielbut/pointy v1.1.0 github.com/spf13/cast v1.5.0 github.com/terraform-providers/terraform-provider-aws v1.60.1-0.20210625132053-af2d5c0ad54f - go.mongodb.org/atlas v0.18.1-0.20221109142841-f9f8ebe7b9b9 + go.mongodb.org/atlas v0.19.0 go.mongodb.org/realm v0.1.0 ) diff --git a/go.sum b/go.sum index 234ae42a33..103fa1981f 100644 --- a/go.sum +++ b/go.sum @@ -921,6 +921,8 @@ go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6y go.mongodb.org/atlas v0.12.0/go.mod h1:wVCnHcm/7/IfTjEB6K8K35PLG70yGz8BdkRwX0oK9/M= go.mongodb.org/atlas v0.18.1-0.20221109142841-f9f8ebe7b9b9 h1:9m35o4kyRYjwbsIb/lPrjxJ6afPpn9zwOF5i3SIY5Lg= go.mongodb.org/atlas v0.18.1-0.20221109142841-f9f8ebe7b9b9/go.mod h1:PFk1IGhiGjFXHGVspOK7i1U2nnPjK8wAjYwQf6FoVf4= +go.mongodb.org/atlas v0.19.0 h1:gvezG9d0KsSDaExEdTtcGqZHRvvVazzuEcBUpBXxmlg= +go.mongodb.org/atlas v0.19.0/go.mod h1:PFk1IGhiGjFXHGVspOK7i1U2nnPjK8wAjYwQf6FoVf4= go.mongodb.org/realm v0.1.0 h1:zJiXyLaZrznQ+Pz947ziSrDKUep39DO4SfA0Fzx8M4M= go.mongodb.org/realm v0.1.0/go.mod h1:4Vj6iy+Puo1TDERcoh4XZ+pjtwbOzPpzqy3Cwe8ZmDM= go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= diff --git a/mongodbatlas/config.go b/mongodbatlas/config.go index dcf7ad0900..97327963bb 100644 --- a/mongodbatlas/config.go +++ b/mongodbatlas/config.go @@ -20,6 +20,7 @@ type Config struct { PrivateKey string BaseURL string RealmBaseURL string + AssumeRole *AssumeRole } // MongoDBClient client diff --git a/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go b/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go index ea91930962..65f6473eae 100644 --- a/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go +++ b/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go @@ -104,9 +104,9 @@ func dataSourceMongoDBAtlasCloudBackupSnapshotsExportJobRead(ctx context.Context ids := decodeStateID(d.Id()) projectID := ids["project_id"] clusterName := ids["cluster_name"] - exportJobID := ids["export_job_id"] + exportID := ids["export_job_id"] - exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportJobID) + exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportID) if err != nil { return diag.Errorf("error getting snapshot export job information: %s", err) } diff --git a/mongodbatlas/provider.go b/mongodbatlas/provider.go index 2d144e20f7..0ea70465c3 100644 --- a/mongodbatlas/provider.go +++ b/mongodbatlas/provider.go @@ -3,17 +3,28 @@ package mongodbatlas import ( "context" "encoding/base64" + "encoding/json" "fmt" "hash/crc32" "log" "os" "reflect" + "regexp" "sort" "strconv" "strings" - + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/endpoints" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/secretsmanager" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/mwielbut/pointy" "github.com/spf13/cast" matlas "go.mongodb.org/atlas/mongodbatlas" @@ -24,6 +35,11 @@ var ( baseURL = "" ) +type SecretData struct { + PublicKey string `json:"public_key"` + PrivateKey string `json:"private_key"` +} + // Provider returns the provider to be use by the code. func Provider() *schema.Provider { provider := &schema.Provider{ @@ -67,6 +83,51 @@ func Provider() *schema.Provider { Optional: true, Description: "MongoDB Atlas Base URL default to gov", }, + "assume_role": assumeRoleSchema(), + "secret_name": { + Type: schema.TypeString, + Optional: true, + }, + "region": { + Type: schema.TypeString, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "AWS_REGION", + "TF_VAR_AWS_REGION", + }, ""), + Optional: true, + }, + "sts_endpoint": { + Type: schema.TypeString, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "STS_ENDPOINT", + "TF_VAR_STS_ENDPOINT", + }, ""), + Optional: true, + }, + "aws_access_key_id": { + Type: schema.TypeString, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "AWS_ACCESS_KEY_ID", + "TF_VAR_AWS_ACCESS_KEY_ID", + }, ""), + Optional: true, + }, + "aws_secret_access_key": { + Type: schema.TypeString, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "AWS_SECRET_ACCESS_KEY", + "TF_VAR_AWS_SECRET_ACCESS_KEY", + }, ""), + Optional: true, + }, + "aws_session_token": { + Type: schema.TypeString, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "AWS_SESSION_TOKEN", + "TF_VAR_AWS_SESSION_TOKEN", + }, ""), + Optional: true, + }, }, DataSourcesMap: getDataSourcesMap(), ResourcesMap: getResourcesMap(), @@ -226,9 +287,79 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{} RealmBaseURL: d.Get("realm_base_url").(string), } + if v, ok := d.GetOk("assume_role"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + config.AssumeRole = expandAssumeRole(v.([]interface{})[0].(map[string]interface{})) + secret := d.Get("secret_name").(string) + region := d.Get("region").(string) + awsAccessKeyID := d.Get("aws_access_key_id").(string) + awsSecretAccessKey := d.Get("aws_secret_access_key").(string) + awsSessionToken := d.Get("aws_session_token").(string) + endpoint := d.Get("sts_endpoint").(string) + config, _ = configureCredentialsSTS(&config, secret, region, awsAccessKeyID, awsSecretAccessKey, awsSessionToken, endpoint) + } + return config.NewClient(ctx) } +func configureCredentialsSTS(config *Config, secret, region, awsAccessKeyID, awsSecretAccessKey, awsSessionToken, endpoint string) (Config, error) { + ep, _ := endpoints.GetSTSRegionalEndpoint("regional") + sess := session.Must(session.NewSession(&aws.Config{ + Region: aws.String(region), + Credentials: credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, awsSessionToken), + STSRegionalEndpoint: ep, + Endpoint: &endpoint, + })) + + creds := stscreds.NewCredentials(sess, config.AssumeRole.RoleARN) + + _, _ = sess.Config.Credentials.Get() + _, _ = creds.Get() + secretString := secretsManagerGetSecretValue(sess, &aws.Config{Credentials: creds, Region: aws.String(region)}, secret) + + var secretData SecretData + err := json.Unmarshal([]byte(secretString), &secretData) + if err != nil { + return *config, nil + } + config.PublicKey = secretData.PublicKey + config.PrivateKey = secretData.PrivateKey + return *config, nil +} + +func secretsManagerGetSecretValue(sess *session.Session, creds *aws.Config, secret string) string { + svc := secretsmanager.New(sess, creds) + input := &secretsmanager.GetSecretValueInput{ + SecretId: aws.String(secret), + VersionStage: aws.String("AWSCURRENT"), + } + + result, err := svc.GetSecretValue(input) + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + switch aerr.Code() { + case secretsmanager.ErrCodeResourceNotFoundException: + fmt.Println(secretsmanager.ErrCodeResourceNotFoundException, aerr.Error()) + case secretsmanager.ErrCodeInvalidParameterException: + fmt.Println(secretsmanager.ErrCodeInvalidParameterException, aerr.Error()) + case secretsmanager.ErrCodeInvalidRequestException: + fmt.Println(secretsmanager.ErrCodeInvalidRequestException, aerr.Error()) + case secretsmanager.ErrCodeDecryptionFailure: + fmt.Println(secretsmanager.ErrCodeDecryptionFailure, aerr.Error()) + case secretsmanager.ErrCodeInternalServiceError: + fmt.Println(secretsmanager.ErrCodeInternalServiceError, aerr.Error()) + default: + fmt.Println(aerr.Error()) + } + } else { + fmt.Println(err.Error()) + } + return "" + } + + fmt.Println(result) + return *result.SecretString +} + func encodeStateID(values map[string]string) string { encode := func(e string) string { return base64.StdEncoding.EncodeToString([]byte(e)) } encodedValues := make([]string, 0) @@ -391,3 +522,167 @@ func HashCodeString(s string) int { // v == MinInt return 0 } + +// assumeRoleSchema From aws provider.go +func assumeRoleSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "duration": { + Type: schema.TypeString, + Optional: true, + Description: "The duration, between 15 minutes and 12 hours, of the role session. Valid time units are ns, us (or µs), ms, s, h, or m.", + ValidateFunc: validAssumeRoleDuration, + ConflictsWith: []string{"assume_role.0.duration_seconds"}, + }, + "duration_seconds": { + Type: schema.TypeInt, + Optional: true, + Deprecated: "Use assume_role.duration instead", + Description: "The duration, in seconds, of the role session.", + ValidateFunc: validation.IntBetween(900, 43200), + ConflictsWith: []string{"assume_role.0.duration"}, + }, + "external_id": { + Type: schema.TypeString, + Optional: true, + Description: "A unique identifier that might be required when you assume a role in another account.", + ValidateFunc: validation.All( + validation.StringLenBetween(2, 1224), + validation.StringMatch(regexp.MustCompile(`[\w+=,.@:/\-]*`), ""), + ), + }, + "policy": { + Type: schema.TypeString, + Optional: true, + Description: "IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.", + ValidateFunc: validation.StringIsJSON, + }, + "policy_arns": { + Type: schema.TypeSet, + Optional: true, + Description: "Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "role_arn": { + Type: schema.TypeString, + Optional: true, + Description: "Amazon Resource Name (ARN) of an IAM Role to assume prior to making API calls.", + }, + "session_name": { + Type: schema.TypeString, + Optional: true, + Description: "An identifier for the assumed role session.", + ValidateFunc: validAssumeRoleSessionName, + }, + "source_identity": { + Type: schema.TypeString, + Optional: true, + Description: "Source identity specified by the principal assuming the role.", + ValidateFunc: validAssumeRoleSourceIdentity, + }, + "tags": { + Type: schema.TypeMap, + Optional: true, + Description: "Assume role session tags.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "transitive_tag_keys": { + Type: schema.TypeSet, + Optional: true, + Description: "Assume role session tag keys to pass to any subsequent sessions.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + } +} + +var validAssumeRoleSessionName = validation.All( + validation.StringLenBetween(2, 64), + validation.StringMatch(regexp.MustCompile(`[\w+=,.@\-]*`), ""), +) + +var validAssumeRoleSourceIdentity = validation.All( + validation.StringLenBetween(2, 64), + validation.StringMatch(regexp.MustCompile(`[\w+=,.@\-]*`), ""), +) + +// validAssumeRoleDuration validates a string can be parsed as a valid time.Duration +// and is within a minimum of 15 minutes and maximum of 12 hours +func validAssumeRoleDuration(v interface{}, k string) (ws []string, errors []error) { + duration, err := time.ParseDuration(v.(string)) + + if err != nil { + errors = append(errors, fmt.Errorf("%q cannot be parsed as a duration: %w", k, err)) + return + } + + if duration.Minutes() < 15 || duration.Hours() > 12 { + errors = append(errors, fmt.Errorf("duration %q must be between 15 minutes (15m) and 12 hours (12h), inclusive", k)) + } + + return +} + +type AssumeRole struct { + RoleARN string + Duration time.Duration + ExternalID string + Policy string + PolicyARNs []string + SessionName string + SourceIdentity string + Tags map[string]string + TransitiveTagKeys []string +} + +func expandAssumeRole(tfMap map[string]interface{}) *AssumeRole { + if tfMap == nil { + return nil + } + + assumeRole := AssumeRole{} + + if v, ok := tfMap["duration"].(string); ok && v != "" { + duration, _ := time.ParseDuration(v) + assumeRole.Duration = duration + } else if v, ok := tfMap["duration_seconds"].(int); ok && v != 0 { + assumeRole.Duration = time.Duration(v) * time.Second + } + + if v, ok := tfMap["external_id"].(string); ok && v != "" { + assumeRole.ExternalID = v + } + + if v, ok := tfMap["policy"].(string); ok && v != "" { + assumeRole.Policy = v + } + + if v, ok := tfMap["policy_arns"].(*schema.Set); ok && v.Len() > 0 { + assumeRole.PolicyARNs = expandStringList(v.List()) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + assumeRole.RoleARN = v + } + + if v, ok := tfMap["session_name"].(string); ok && v != "" { + assumeRole.SessionName = v + } + + if v, ok := tfMap["source_identity"].(string); ok && v != "" { + assumeRole.SourceIdentity = v + } + + if v, ok := tfMap["transitive_tag_keys"].(*schema.Set); ok && v.Len() > 0 { + assumeRole.TransitiveTagKeys = expandStringList(v.List()) + } + + return &assumeRole +} diff --git a/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go b/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go index e0652ac408..1d3f3bda8e 100644 --- a/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go +++ b/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go @@ -124,9 +124,9 @@ func resourceMongoDBAtlasCloudBackupSnapshotExportJobRead(ctx context.Context, d ids := decodeStateID(d.Id()) projectID := ids["project_id"] clusterName := ids["cluster_name"] - exportJobID := ids["export_job_id"] + exportID := ids["export_job_id"] - exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportJobID) + exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportID) if err != nil { // case 404 // deleted in the backend case @@ -278,17 +278,17 @@ func resourceMongoDBAtlasCloudBackupSnapshotExportJobImportState(ctx context.Con projectID := parts[0] clusterName := parts[1] - exportJobID := parts[2] + exportID := parts[2] - _, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportJobID) + _, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportID) if err != nil { - return nil, fmt.Errorf("couldn't import snapshot export job %s in project %s and cluster %s, error: %s", exportJobID, projectID, clusterName, err) + return nil, fmt.Errorf("couldn't import snapshot export job %s in project %s and cluster %s, error: %s", exportID, projectID, clusterName, err) } d.SetId(encodeStateID(map[string]string{ "project_id": projectID, "cluster_name": clusterName, - "export_job_id": exportJobID, + "export_job_id": exportID, })) return []*schema.ResourceData{d}, nil diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 64ad25efe3..e27c6a0e7f 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -33,6 +33,8 @@ The [MongoDB Atlas documentation](https://docs.atlas.mongodb.com/tutorial/manage **Role**: If unsure of which role level to grant your key, we suggest creating an organization API Key with an Organization Owner role. This ensures that you have sufficient access for all actions. +**API Key Access List**: Some Atlas API resources such as Cloud Backup Restores, Cloud Backup Snapshots, and Cloud Backup Schedules **require** an Atlas API Key Access List to utilize these feature. Hence, if using Terraform, or any other programmatic control, to manage these resources you must have the IP address or CIDR block that the connection is coming from added to the Atlas API Key Access List of the Atlas API key you are using. See [Resources that require API Key List](https://www.mongodb.com/docs/atlas/configure-api-access/#use-api-resources-that-require-an-access-list) + ## Configure MongoDB Atlas for Government In order to enable the Terraform MongoDB Atlas Provider for use with MongoDB Atlas for Government add is_mongodbgov_cloud = true to your provider configuration: @@ -47,7 +49,6 @@ provider "mongodbatlas" { ``` Also see [`Atlas for Government Considerations`](https://www.mongodb.com/docs/atlas/government/api/#atlas-for-government-considerations). -**API Key Access List**: Some Atlas API resources such as Cloud Backup Restores, Cloud Backup Snapshots, and Cloud Backup Schedules **require** an Atlas API Key Access List to utilize these feature. Hence, if using Terraform, or any other programmatic control, to manage these resources you must have the IP address or CIDR block that the connection is coming from added to the Atlas API Key Access List of the Atlas API key you are using. See [Resources that require API Key List](https://www.mongodb.com/docs/atlas/configure-api-access/#use-api-resources-that-require-an-access-list) ## Authenticate the Provider The MongoDB Atlas provider offers a flexible means of providing credentials for authentication. @@ -75,6 +76,34 @@ As an alternative to `MONGODB_ATLAS_PUBLIC_KEY` and `MONGODB_ATLAS_PRIVATE_KEY` if you are using [MongoDB CLI](https://docs.mongodb.com/mongocli/stable/) then `MCLI_PUBLIC_API_KEY` and `MCLI_PRIVATE_API_KEY` are also supported. +### AWS Secrets Manager +AWS Secrets Manager (AWS SM) helps to manage, retrieve, and rotate database credentials, API keys, and other secrets throughout their lifecycles. See [product page](https://aws.amazon.com/secrets-manager/) and [documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html) for more details. + +In order to enable the Terraform MongoDB Atlas Provider to use AWS SM, first create Atlas API Keys and add them as a secret to AWS SM with a basic key with a raw value. See below example: +``` + { + "public_key": "iepubky", + "private_key":"prvkey" + } +``` + +Next, add assume_role block with `role_arn`, `secret_name`, and AWS `region` to match the AWS region where secret is stored with AWS SM. See below example: +```terraform +# Configure the MongoDB Atlas Provider to Authenticate with AWS Secrets Manager +provider "mongodbatlas" { + assume_role { + role_arn = "arn:aws:iam::476xxx451:role/mdbsts" + } + secret_name = "mongodbsecret" + aws_access_key_id = "ASIXXBNEK" + aws_secret_access_key = "ZUZgVb8XYZWEXXEDURGFHFc5Au" + aws_session_token = "IQoXX3+Q=" + region = "us-east-2" + sts_endpoint = "https://sts.us-east-2.amazonaws.com/" +} +``` +Note: `aws_access_key_id`, `aws_secret_access_key`, `aws_session_token`, `region` can also be passed in using environment variables i.e. aws_access_key_id will accept AWS_ACCESS_KEY_ID and TF_VAR_AWS_ACCESS_KEY_ID as a default value in place of value in a terraform file variable. + ### Static Credentials Static credentials can be provided by adding the following attributes in-line in the MongoDB Atlas provider block, diff --git a/website/mongodbatlas.erb b/website/mongodbatlas.erb deleted file mode 100644 index 2ca0c028e3..0000000000 --- a/website/mongodbatlas.erb +++ /dev/null @@ -1,243 +0,0 @@ -<% wrap_layout :inner do %> - <% content_for :sidebar do %> - - <% end %> - - <%= yield %> -<% end %> From 4d44f08e81c463c7d57dc04fc6fe6d599313a1d6 Mon Sep 17 00:00:00 2001 From: Zuhair Ahmed Date: Thu, 22 Dec 2022 14:35:54 -0500 Subject: [PATCH 04/10] Revert "v1.7.0 Pre-Release (#980)" (#982) This reverts commit 7a57d21bd7f919994f7d3a7ff2728ff049717f60. --- .github_changelog_generator | 4 +- go.mod | 2 +- go.sum | 2 - mongodbatlas/config.go | 1 - ...batlas_cloud_backup_snapshot_export_job.go | 4 +- mongodbatlas/provider.go | 297 +----------------- ...batlas_cloud_backup_snapshot_export_job.go | 12 +- website/docs/index.html.markdown | 31 +- website/mongodbatlas.erb | 243 ++++++++++++++ 9 files changed, 256 insertions(+), 340 deletions(-) create mode 100644 website/mongodbatlas.erb diff --git a/.github_changelog_generator b/.github_changelog_generator index 29056cc9e7..0492113c4c 100644 --- a/.github_changelog_generator +++ b/.github_changelog_generator @@ -1,4 +1,4 @@ -future-release=v1.7.0 -since-tag=v1.6.1 +future-release=v1.6.1 +since-tag=v1.6.0 date-format=%B %d, %Y base=CHANGELOG.md diff --git a/go.mod b/go.mod index 554e240f7e..eb6e51b327 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/mwielbut/pointy v1.1.0 github.com/spf13/cast v1.5.0 github.com/terraform-providers/terraform-provider-aws v1.60.1-0.20210625132053-af2d5c0ad54f - go.mongodb.org/atlas v0.19.0 + go.mongodb.org/atlas v0.18.1-0.20221109142841-f9f8ebe7b9b9 go.mongodb.org/realm v0.1.0 ) diff --git a/go.sum b/go.sum index 103fa1981f..234ae42a33 100644 --- a/go.sum +++ b/go.sum @@ -921,8 +921,6 @@ go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6y go.mongodb.org/atlas v0.12.0/go.mod h1:wVCnHcm/7/IfTjEB6K8K35PLG70yGz8BdkRwX0oK9/M= go.mongodb.org/atlas v0.18.1-0.20221109142841-f9f8ebe7b9b9 h1:9m35o4kyRYjwbsIb/lPrjxJ6afPpn9zwOF5i3SIY5Lg= go.mongodb.org/atlas v0.18.1-0.20221109142841-f9f8ebe7b9b9/go.mod h1:PFk1IGhiGjFXHGVspOK7i1U2nnPjK8wAjYwQf6FoVf4= -go.mongodb.org/atlas v0.19.0 h1:gvezG9d0KsSDaExEdTtcGqZHRvvVazzuEcBUpBXxmlg= -go.mongodb.org/atlas v0.19.0/go.mod h1:PFk1IGhiGjFXHGVspOK7i1U2nnPjK8wAjYwQf6FoVf4= go.mongodb.org/realm v0.1.0 h1:zJiXyLaZrznQ+Pz947ziSrDKUep39DO4SfA0Fzx8M4M= go.mongodb.org/realm v0.1.0/go.mod h1:4Vj6iy+Puo1TDERcoh4XZ+pjtwbOzPpzqy3Cwe8ZmDM= go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= diff --git a/mongodbatlas/config.go b/mongodbatlas/config.go index 97327963bb..dcf7ad0900 100644 --- a/mongodbatlas/config.go +++ b/mongodbatlas/config.go @@ -20,7 +20,6 @@ type Config struct { PrivateKey string BaseURL string RealmBaseURL string - AssumeRole *AssumeRole } // MongoDBClient client diff --git a/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go b/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go index 65f6473eae..ea91930962 100644 --- a/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go +++ b/mongodbatlas/data_source_mongodbatlas_cloud_backup_snapshot_export_job.go @@ -104,9 +104,9 @@ func dataSourceMongoDBAtlasCloudBackupSnapshotsExportJobRead(ctx context.Context ids := decodeStateID(d.Id()) projectID := ids["project_id"] clusterName := ids["cluster_name"] - exportID := ids["export_job_id"] + exportJobID := ids["export_job_id"] - exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportID) + exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportJobID) if err != nil { return diag.Errorf("error getting snapshot export job information: %s", err) } diff --git a/mongodbatlas/provider.go b/mongodbatlas/provider.go index 0ea70465c3..2d144e20f7 100644 --- a/mongodbatlas/provider.go +++ b/mongodbatlas/provider.go @@ -3,28 +3,17 @@ package mongodbatlas import ( "context" "encoding/base64" - "encoding/json" "fmt" "hash/crc32" "log" "os" "reflect" - "regexp" "sort" "strconv" "strings" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/credentials/stscreds" - "github.com/aws/aws-sdk-go/aws/endpoints" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/secretsmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/mwielbut/pointy" "github.com/spf13/cast" matlas "go.mongodb.org/atlas/mongodbatlas" @@ -35,11 +24,6 @@ var ( baseURL = "" ) -type SecretData struct { - PublicKey string `json:"public_key"` - PrivateKey string `json:"private_key"` -} - // Provider returns the provider to be use by the code. func Provider() *schema.Provider { provider := &schema.Provider{ @@ -83,51 +67,6 @@ func Provider() *schema.Provider { Optional: true, Description: "MongoDB Atlas Base URL default to gov", }, - "assume_role": assumeRoleSchema(), - "secret_name": { - Type: schema.TypeString, - Optional: true, - }, - "region": { - Type: schema.TypeString, - DefaultFunc: schema.MultiEnvDefaultFunc([]string{ - "AWS_REGION", - "TF_VAR_AWS_REGION", - }, ""), - Optional: true, - }, - "sts_endpoint": { - Type: schema.TypeString, - DefaultFunc: schema.MultiEnvDefaultFunc([]string{ - "STS_ENDPOINT", - "TF_VAR_STS_ENDPOINT", - }, ""), - Optional: true, - }, - "aws_access_key_id": { - Type: schema.TypeString, - DefaultFunc: schema.MultiEnvDefaultFunc([]string{ - "AWS_ACCESS_KEY_ID", - "TF_VAR_AWS_ACCESS_KEY_ID", - }, ""), - Optional: true, - }, - "aws_secret_access_key": { - Type: schema.TypeString, - DefaultFunc: schema.MultiEnvDefaultFunc([]string{ - "AWS_SECRET_ACCESS_KEY", - "TF_VAR_AWS_SECRET_ACCESS_KEY", - }, ""), - Optional: true, - }, - "aws_session_token": { - Type: schema.TypeString, - DefaultFunc: schema.MultiEnvDefaultFunc([]string{ - "AWS_SESSION_TOKEN", - "TF_VAR_AWS_SESSION_TOKEN", - }, ""), - Optional: true, - }, }, DataSourcesMap: getDataSourcesMap(), ResourcesMap: getResourcesMap(), @@ -287,79 +226,9 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{} RealmBaseURL: d.Get("realm_base_url").(string), } - if v, ok := d.GetOk("assume_role"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - config.AssumeRole = expandAssumeRole(v.([]interface{})[0].(map[string]interface{})) - secret := d.Get("secret_name").(string) - region := d.Get("region").(string) - awsAccessKeyID := d.Get("aws_access_key_id").(string) - awsSecretAccessKey := d.Get("aws_secret_access_key").(string) - awsSessionToken := d.Get("aws_session_token").(string) - endpoint := d.Get("sts_endpoint").(string) - config, _ = configureCredentialsSTS(&config, secret, region, awsAccessKeyID, awsSecretAccessKey, awsSessionToken, endpoint) - } - return config.NewClient(ctx) } -func configureCredentialsSTS(config *Config, secret, region, awsAccessKeyID, awsSecretAccessKey, awsSessionToken, endpoint string) (Config, error) { - ep, _ := endpoints.GetSTSRegionalEndpoint("regional") - sess := session.Must(session.NewSession(&aws.Config{ - Region: aws.String(region), - Credentials: credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, awsSessionToken), - STSRegionalEndpoint: ep, - Endpoint: &endpoint, - })) - - creds := stscreds.NewCredentials(sess, config.AssumeRole.RoleARN) - - _, _ = sess.Config.Credentials.Get() - _, _ = creds.Get() - secretString := secretsManagerGetSecretValue(sess, &aws.Config{Credentials: creds, Region: aws.String(region)}, secret) - - var secretData SecretData - err := json.Unmarshal([]byte(secretString), &secretData) - if err != nil { - return *config, nil - } - config.PublicKey = secretData.PublicKey - config.PrivateKey = secretData.PrivateKey - return *config, nil -} - -func secretsManagerGetSecretValue(sess *session.Session, creds *aws.Config, secret string) string { - svc := secretsmanager.New(sess, creds) - input := &secretsmanager.GetSecretValueInput{ - SecretId: aws.String(secret), - VersionStage: aws.String("AWSCURRENT"), - } - - result, err := svc.GetSecretValue(input) - if err != nil { - if aerr, ok := err.(awserr.Error); ok { - switch aerr.Code() { - case secretsmanager.ErrCodeResourceNotFoundException: - fmt.Println(secretsmanager.ErrCodeResourceNotFoundException, aerr.Error()) - case secretsmanager.ErrCodeInvalidParameterException: - fmt.Println(secretsmanager.ErrCodeInvalidParameterException, aerr.Error()) - case secretsmanager.ErrCodeInvalidRequestException: - fmt.Println(secretsmanager.ErrCodeInvalidRequestException, aerr.Error()) - case secretsmanager.ErrCodeDecryptionFailure: - fmt.Println(secretsmanager.ErrCodeDecryptionFailure, aerr.Error()) - case secretsmanager.ErrCodeInternalServiceError: - fmt.Println(secretsmanager.ErrCodeInternalServiceError, aerr.Error()) - default: - fmt.Println(aerr.Error()) - } - } else { - fmt.Println(err.Error()) - } - return "" - } - - fmt.Println(result) - return *result.SecretString -} - func encodeStateID(values map[string]string) string { encode := func(e string) string { return base64.StdEncoding.EncodeToString([]byte(e)) } encodedValues := make([]string, 0) @@ -522,167 +391,3 @@ func HashCodeString(s string) int { // v == MinInt return 0 } - -// assumeRoleSchema From aws provider.go -func assumeRoleSchema() *schema.Schema { - return &schema.Schema{ - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "duration": { - Type: schema.TypeString, - Optional: true, - Description: "The duration, between 15 minutes and 12 hours, of the role session. Valid time units are ns, us (or µs), ms, s, h, or m.", - ValidateFunc: validAssumeRoleDuration, - ConflictsWith: []string{"assume_role.0.duration_seconds"}, - }, - "duration_seconds": { - Type: schema.TypeInt, - Optional: true, - Deprecated: "Use assume_role.duration instead", - Description: "The duration, in seconds, of the role session.", - ValidateFunc: validation.IntBetween(900, 43200), - ConflictsWith: []string{"assume_role.0.duration"}, - }, - "external_id": { - Type: schema.TypeString, - Optional: true, - Description: "A unique identifier that might be required when you assume a role in another account.", - ValidateFunc: validation.All( - validation.StringLenBetween(2, 1224), - validation.StringMatch(regexp.MustCompile(`[\w+=,.@:/\-]*`), ""), - ), - }, - "policy": { - Type: schema.TypeString, - Optional: true, - Description: "IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.", - ValidateFunc: validation.StringIsJSON, - }, - "policy_arns": { - Type: schema.TypeSet, - Optional: true, - Description: "Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "role_arn": { - Type: schema.TypeString, - Optional: true, - Description: "Amazon Resource Name (ARN) of an IAM Role to assume prior to making API calls.", - }, - "session_name": { - Type: schema.TypeString, - Optional: true, - Description: "An identifier for the assumed role session.", - ValidateFunc: validAssumeRoleSessionName, - }, - "source_identity": { - Type: schema.TypeString, - Optional: true, - Description: "Source identity specified by the principal assuming the role.", - ValidateFunc: validAssumeRoleSourceIdentity, - }, - "tags": { - Type: schema.TypeMap, - Optional: true, - Description: "Assume role session tags.", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "transitive_tag_keys": { - Type: schema.TypeSet, - Optional: true, - Description: "Assume role session tag keys to pass to any subsequent sessions.", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - }, - }, - } -} - -var validAssumeRoleSessionName = validation.All( - validation.StringLenBetween(2, 64), - validation.StringMatch(regexp.MustCompile(`[\w+=,.@\-]*`), ""), -) - -var validAssumeRoleSourceIdentity = validation.All( - validation.StringLenBetween(2, 64), - validation.StringMatch(regexp.MustCompile(`[\w+=,.@\-]*`), ""), -) - -// validAssumeRoleDuration validates a string can be parsed as a valid time.Duration -// and is within a minimum of 15 minutes and maximum of 12 hours -func validAssumeRoleDuration(v interface{}, k string) (ws []string, errors []error) { - duration, err := time.ParseDuration(v.(string)) - - if err != nil { - errors = append(errors, fmt.Errorf("%q cannot be parsed as a duration: %w", k, err)) - return - } - - if duration.Minutes() < 15 || duration.Hours() > 12 { - errors = append(errors, fmt.Errorf("duration %q must be between 15 minutes (15m) and 12 hours (12h), inclusive", k)) - } - - return -} - -type AssumeRole struct { - RoleARN string - Duration time.Duration - ExternalID string - Policy string - PolicyARNs []string - SessionName string - SourceIdentity string - Tags map[string]string - TransitiveTagKeys []string -} - -func expandAssumeRole(tfMap map[string]interface{}) *AssumeRole { - if tfMap == nil { - return nil - } - - assumeRole := AssumeRole{} - - if v, ok := tfMap["duration"].(string); ok && v != "" { - duration, _ := time.ParseDuration(v) - assumeRole.Duration = duration - } else if v, ok := tfMap["duration_seconds"].(int); ok && v != 0 { - assumeRole.Duration = time.Duration(v) * time.Second - } - - if v, ok := tfMap["external_id"].(string); ok && v != "" { - assumeRole.ExternalID = v - } - - if v, ok := tfMap["policy"].(string); ok && v != "" { - assumeRole.Policy = v - } - - if v, ok := tfMap["policy_arns"].(*schema.Set); ok && v.Len() > 0 { - assumeRole.PolicyARNs = expandStringList(v.List()) - } - - if v, ok := tfMap["role_arn"].(string); ok && v != "" { - assumeRole.RoleARN = v - } - - if v, ok := tfMap["session_name"].(string); ok && v != "" { - assumeRole.SessionName = v - } - - if v, ok := tfMap["source_identity"].(string); ok && v != "" { - assumeRole.SourceIdentity = v - } - - if v, ok := tfMap["transitive_tag_keys"].(*schema.Set); ok && v.Len() > 0 { - assumeRole.TransitiveTagKeys = expandStringList(v.List()) - } - - return &assumeRole -} diff --git a/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go b/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go index 1d3f3bda8e..e0652ac408 100644 --- a/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go +++ b/mongodbatlas/resource_mongodbatlas_cloud_backup_snapshot_export_job.go @@ -124,9 +124,9 @@ func resourceMongoDBAtlasCloudBackupSnapshotExportJobRead(ctx context.Context, d ids := decodeStateID(d.Id()) projectID := ids["project_id"] clusterName := ids["cluster_name"] - exportID := ids["export_job_id"] + exportJobID := ids["export_job_id"] - exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportID) + exportJob, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportJobID) if err != nil { // case 404 // deleted in the backend case @@ -278,17 +278,17 @@ func resourceMongoDBAtlasCloudBackupSnapshotExportJobImportState(ctx context.Con projectID := parts[0] clusterName := parts[1] - exportID := parts[2] + exportJobID := parts[2] - _, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportID) + _, _, err := conn.CloudProviderSnapshotExportJobs.Get(ctx, projectID, clusterName, exportJobID) if err != nil { - return nil, fmt.Errorf("couldn't import snapshot export job %s in project %s and cluster %s, error: %s", exportID, projectID, clusterName, err) + return nil, fmt.Errorf("couldn't import snapshot export job %s in project %s and cluster %s, error: %s", exportJobID, projectID, clusterName, err) } d.SetId(encodeStateID(map[string]string{ "project_id": projectID, "cluster_name": clusterName, - "export_job_id": exportID, + "export_job_id": exportJobID, })) return []*schema.ResourceData{d}, nil diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index e27c6a0e7f..64ad25efe3 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -33,8 +33,6 @@ The [MongoDB Atlas documentation](https://docs.atlas.mongodb.com/tutorial/manage **Role**: If unsure of which role level to grant your key, we suggest creating an organization API Key with an Organization Owner role. This ensures that you have sufficient access for all actions. -**API Key Access List**: Some Atlas API resources such as Cloud Backup Restores, Cloud Backup Snapshots, and Cloud Backup Schedules **require** an Atlas API Key Access List to utilize these feature. Hence, if using Terraform, or any other programmatic control, to manage these resources you must have the IP address or CIDR block that the connection is coming from added to the Atlas API Key Access List of the Atlas API key you are using. See [Resources that require API Key List](https://www.mongodb.com/docs/atlas/configure-api-access/#use-api-resources-that-require-an-access-list) - ## Configure MongoDB Atlas for Government In order to enable the Terraform MongoDB Atlas Provider for use with MongoDB Atlas for Government add is_mongodbgov_cloud = true to your provider configuration: @@ -49,6 +47,7 @@ provider "mongodbatlas" { ``` Also see [`Atlas for Government Considerations`](https://www.mongodb.com/docs/atlas/government/api/#atlas-for-government-considerations). +**API Key Access List**: Some Atlas API resources such as Cloud Backup Restores, Cloud Backup Snapshots, and Cloud Backup Schedules **require** an Atlas API Key Access List to utilize these feature. Hence, if using Terraform, or any other programmatic control, to manage these resources you must have the IP address or CIDR block that the connection is coming from added to the Atlas API Key Access List of the Atlas API key you are using. See [Resources that require API Key List](https://www.mongodb.com/docs/atlas/configure-api-access/#use-api-resources-that-require-an-access-list) ## Authenticate the Provider The MongoDB Atlas provider offers a flexible means of providing credentials for authentication. @@ -76,34 +75,6 @@ As an alternative to `MONGODB_ATLAS_PUBLIC_KEY` and `MONGODB_ATLAS_PRIVATE_KEY` if you are using [MongoDB CLI](https://docs.mongodb.com/mongocli/stable/) then `MCLI_PUBLIC_API_KEY` and `MCLI_PRIVATE_API_KEY` are also supported. -### AWS Secrets Manager -AWS Secrets Manager (AWS SM) helps to manage, retrieve, and rotate database credentials, API keys, and other secrets throughout their lifecycles. See [product page](https://aws.amazon.com/secrets-manager/) and [documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html) for more details. - -In order to enable the Terraform MongoDB Atlas Provider to use AWS SM, first create Atlas API Keys and add them as a secret to AWS SM with a basic key with a raw value. See below example: -``` - { - "public_key": "iepubky", - "private_key":"prvkey" - } -``` - -Next, add assume_role block with `role_arn`, `secret_name`, and AWS `region` to match the AWS region where secret is stored with AWS SM. See below example: -```terraform -# Configure the MongoDB Atlas Provider to Authenticate with AWS Secrets Manager -provider "mongodbatlas" { - assume_role { - role_arn = "arn:aws:iam::476xxx451:role/mdbsts" - } - secret_name = "mongodbsecret" - aws_access_key_id = "ASIXXBNEK" - aws_secret_access_key = "ZUZgVb8XYZWEXXEDURGFHFc5Au" - aws_session_token = "IQoXX3+Q=" - region = "us-east-2" - sts_endpoint = "https://sts.us-east-2.amazonaws.com/" -} -``` -Note: `aws_access_key_id`, `aws_secret_access_key`, `aws_session_token`, `region` can also be passed in using environment variables i.e. aws_access_key_id will accept AWS_ACCESS_KEY_ID and TF_VAR_AWS_ACCESS_KEY_ID as a default value in place of value in a terraform file variable. - ### Static Credentials Static credentials can be provided by adding the following attributes in-line in the MongoDB Atlas provider block, diff --git a/website/mongodbatlas.erb b/website/mongodbatlas.erb new file mode 100644 index 0000000000..2ca0c028e3 --- /dev/null +++ b/website/mongodbatlas.erb @@ -0,0 +1,243 @@ +<% wrap_layout :inner do %> + <% content_for :sidebar do %> + + <% end %> + + <%= yield %> +<% end %> From 21788e4e2177ef1edfb8dcc67585c02a3c032e55 Mon Sep 17 00:00:00 2001 From: admin <33664051+martinstibbe@users.noreply.github.com> Date: Fri, 23 Dec 2022 19:29:14 -0600 Subject: [PATCH 05/10] Add deprecation notices --- .../data_source_mongodbatlas_cloud_provider_snapshot.go | 2 +- .../data_source_mongodbatlas_cloud_provider_snapshots.go | 2 +- mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot.go | 2 +- mongodbatlas/resource_mongodbatlas_private_ip_mode.go | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot.go b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot.go index 2140313b9f..36abbe4b32 100644 --- a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot.go +++ b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot.go @@ -63,7 +63,7 @@ func dataSourceMongoDBAtlasCloudProviderSnapshot() *schema.Resource { Computed: true, }, }, - DeprecationMessage: "This data source is deprecated. Please transition to mongodbatlas_cloud_backup_snapshot as soon as possible", + DeprecationMessage: "This data source is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_snapshot as soon as possible", } } diff --git a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshots.go b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshots.go index 390a016428..8877a80b21 100644 --- a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshots.go +++ b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshots.go @@ -84,7 +84,7 @@ func dataSourceMongoDBAtlasCloudProviderSnapshots() *schema.Resource { Computed: true, }, }, - DeprecationMessage: "This data source is deprecated. Please transition to mongodbatlas_cloud_backup_snapshots as soon as possible", + DeprecationMessage: "This data source is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_snapshots as soon as possible", } } diff --git a/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot.go b/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot.go index 7b5db522e9..f841cad689 100644 --- a/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot.go +++ b/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot.go @@ -86,7 +86,7 @@ func resourceMongoDBAtlasCloudProviderSnapshot() *schema.Resource { Default: "10m", }, }, - DeprecationMessage: "this resource is deprecated, please transition as soon as possible to mongodbatlas_cloud_backup_snapshot", + DeprecationMessage: "this resource is deprecated, and will be removed in v1.9 release, please transition as soon as possible to mongodbatlas_cloud_backup_snapshot", } } diff --git a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go index b72ea102f6..9824218314 100644 --- a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go +++ b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go @@ -39,7 +39,9 @@ func resourceMongoDBAtlasPrivateIPMode() *schema.Resource { Required: true, }, }, - } + DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_schedule as soon as possible", + }, + } func resourceMongoDBAtlasPrivateIPModeCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { From fd07bd675850956ac3dd6d841e1c1f706944e113 Mon Sep 17 00:00:00 2001 From: admin <33664051+martinstibbe@users.noreply.github.com> Date: Mon, 26 Dec 2022 13:20:22 -0600 Subject: [PATCH 06/10] Additional deprecation details --- ...ource_mongodbatlas_cloud_provider_snapshot_backup_policy.go | 2 +- ..._source_mongodbatlas_cloud_provider_snapshot_restore_job.go | 2 +- ...source_mongodbatlas_cloud_provider_snapshot_restore_jobs.go | 2 +- ...ource_mongodbatlas_cloud_provider_snapshot_backup_policy.go | 2 +- mongodbatlas/resource_mongodbatlas_private_ip_mode.go | 3 +-- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_backup_policy.go b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_backup_policy.go index 7934b059a6..8db4b12457 100644 --- a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_backup_policy.go +++ b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_backup_policy.go @@ -85,7 +85,7 @@ func dataSourceMongoDBAtlasCloudProviderSnapshotBackupPolicy() *schema.Resource }, }, }, - DeprecationMessage: "This data source is deprecated. Please transition to mongodbatlas_cloud_backup_schedule as soon as possible", + DeprecationMessage: "This data source is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_schedule as soon as possible", } } diff --git a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_job.go b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_job.go index ea237c6b2c..0e286cf6da 100644 --- a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_job.go +++ b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_job.go @@ -89,7 +89,7 @@ func dataSourceMongoDBAtlasCloudProviderSnapshotRestoreJob() *schema.Resource { Computed: true, }, }, - DeprecationMessage: "This data source is deprecated. Please transition to mongodbatlas_cloud_backup_snapshot_restore_job as soon as possible", + DeprecationMessage: "This data source is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_snapshot_restore_job as soon as possible", } } diff --git a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_jobs.go b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_jobs.go index 77a57af40f..34819f1e8d 100644 --- a/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_jobs.go +++ b/mongodbatlas/data_source_mongodbatlas_cloud_provider_snapshot_restore_jobs.go @@ -107,7 +107,7 @@ func dataSourceMongoDBAtlasCloudProviderSnapshotRestoreJobs() *schema.Resource { Computed: true, }, }, - DeprecationMessage: "This data source is deprecated. Please transition to mongodbatlas_cloud_backup_snapshot_restore_jobs as soon as possible", + DeprecationMessage: "This data source is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_snapshot_restore_jobs as soon as possible", } } diff --git a/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_backup_policy.go b/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_backup_policy.go index 6f6c666188..977a90a676 100644 --- a/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_backup_policy.go +++ b/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_backup_policy.go @@ -125,7 +125,7 @@ func resourceMongoDBAtlasCloudProviderSnapshotBackupPolicy() *schema.Resource { }, }, }, - DeprecationMessage: "this resource is deprecated, please transition as soon as possible to mongodbatlas_cloud_backup_schedule", + DeprecationMessage: "this resource is deprecated, and will be removed in v1.9 release, please transition as soon as possible to mongodbatlas_cloud_backup_schedule", } } diff --git a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go index 9824218314..4305f528ec 100644 --- a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go +++ b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go @@ -40,8 +40,7 @@ func resourceMongoDBAtlasPrivateIPMode() *schema.Resource { }, }, DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_schedule as soon as possible", - }, - + } } func resourceMongoDBAtlasPrivateIPModeCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { From ec2a220449b045a37da158736537c502c0544e1f Mon Sep 17 00:00:00 2001 From: admin <33664051+martinstibbe@users.noreply.github.com> Date: Mon, 26 Dec 2022 13:52:30 -0600 Subject: [PATCH 07/10] Add more detail --- ...resource_mongodbatlas_cloud_provider_snapshot_restore_job.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_restore_job.go b/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_restore_job.go index 158372555c..f3f446a0dd 100644 --- a/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_restore_job.go +++ b/mongodbatlas/resource_mongodbatlas_cloud_provider_snapshot_restore_job.go @@ -187,7 +187,7 @@ func resourceMongoDBAtlasCloudProviderSnapshotRestoreJob() *schema.Resource { Computed: true, }, }, - DeprecationMessage: "this resource is deprecated, please transition as soon as possible to mongodbatlas_cloud_backup_snapshot_restore_job", + DeprecationMessage: "this resource is deprecated, and will be removed in v1.9 release, please transition as soon as possible to mongodbatlas_cloud_backup_snapshot_restore_job", } } From 56c5c59b71b70d145d9bc5c618b3c79f692ff91a Mon Sep 17 00:00:00 2001 From: admin <33664051+martinstibbe@users.noreply.github.com> Date: Tue, 27 Dec 2022 14:47:32 -0600 Subject: [PATCH 08/10] Update resource_mongodbatlas_private_ip_mode.go --- mongodbatlas/resource_mongodbatlas_private_ip_mode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go index 4305f528ec..0b25226e50 100644 --- a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go +++ b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go @@ -39,7 +39,7 @@ func resourceMongoDBAtlasPrivateIPMode() *schema.Resource { Required: true, }, }, - DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release. Please transition to mongodbatlas_cloud_backup_schedule as soon as possible", + DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release.", } } From 18f8d0ad777f16b073bae0ff0219771c6e75f36f Mon Sep 17 00:00:00 2001 From: admin <33664051+martinstibbe@users.noreply.github.com> Date: Tue, 27 Dec 2022 14:49:15 -0600 Subject: [PATCH 09/10] Update resource_mongodbatlas_private_ip_mode.go --- mongodbatlas/resource_mongodbatlas_private_ip_mode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go index 0b25226e50..5c760b6ea6 100644 --- a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go +++ b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go @@ -39,7 +39,7 @@ func resourceMongoDBAtlasPrivateIPMode() *schema.Resource { Required: true, }, }, - DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release.", + DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release. Please transition to split horizon connection strings as soon as possible", } } From 1aefdcababc9e6a04bb7e826742f7a56c4b13dcd Mon Sep 17 00:00:00 2001 From: admin <33664051+martinstibbe@users.noreply.github.com> Date: Tue, 27 Dec 2022 15:59:33 -0600 Subject: [PATCH 10/10] Update resource_mongodbatlas_private_ip_mode.go --- mongodbatlas/resource_mongodbatlas_private_ip_mode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go index 5c760b6ea6..8a95d280dd 100644 --- a/mongodbatlas/resource_mongodbatlas_private_ip_mode.go +++ b/mongodbatlas/resource_mongodbatlas_private_ip_mode.go @@ -39,7 +39,7 @@ func resourceMongoDBAtlasPrivateIPMode() *schema.Resource { Required: true, }, }, - DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release. Please transition to split horizon connection strings as soon as possible", + DeprecationMessage: "This resource is deprecated, and will be removed in v1.9 release. Please transition to Multiple Horizons connection strings as soon as possible", } }