Skip to content

Commit b49c2fb

Browse files
committed
Merge branch 'master' into v1.8.0_staging
2 parents d84e977 + 3f2b4a1 commit b49c2fb

File tree

3 files changed

+77
-17
lines changed

3 files changed

+77
-17
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ export TF_CLI_CONFIG_FILE=/mnt/c/Users/ZuhairAhmed/Desktop/Tenant_Upgrade/tf_cac
149149
#### Logs
150150
To help with dubbing issues, you can turn on Logs with `export TF_LOG=TRACE`. Note: this is very noisy.
151151

152+
To export logs to file, you can use `export TF_LOG_PATH=terraform.log`
153+
152154
### Running the acceptance test
153155

154156
#### Programmatic API key

mongodbatlas/provider.go

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -296,38 +296,87 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}
296296
awsSecretAccessKey := d.Get("aws_secret_access_key").(string)
297297
awsSessionToken := d.Get("aws_session_token").(string)
298298
endpoint := d.Get("sts_endpoint").(string)
299-
config, _ = configureCredentialsSTS(&config, secret, region, awsAccessKeyID, awsSecretAccessKey, awsSessionToken, endpoint)
299+
var err error
300+
config, err = configureCredentialsSTS(&config, secret, region, awsAccessKeyID, awsSecretAccessKey, awsSessionToken, endpoint)
301+
if err != nil {
302+
return nil, diag.FromErr(err)
303+
}
300304
}
301305

302306
return config.NewClient(ctx)
303307
}
304308

305309
func configureCredentialsSTS(config *Config, secret, region, awsAccessKeyID, awsSecretAccessKey, awsSessionToken, endpoint string) (Config, error) {
306-
ep, _ := endpoints.GetSTSRegionalEndpoint("regional")
307-
sess := session.Must(session.NewSession(&aws.Config{
310+
ep, err := endpoints.GetSTSRegionalEndpoint("regional")
311+
if err != nil {
312+
fmt.Printf("GetSTSRegionalEndpoint error: %s", err)
313+
return *config, err
314+
}
315+
316+
defaultResolver := endpoints.DefaultResolver()
317+
stsCustResolverFn := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
318+
if service == endpoints.StsServiceID {
319+
if endpoint == "" {
320+
return endpoints.ResolvedEndpoint{
321+
URL: "https://sts.amazonaws.com",
322+
SigningRegion: region,
323+
}, nil
324+
}
325+
return endpoints.ResolvedEndpoint{
326+
URL: endpoint,
327+
SigningRegion: region,
328+
}, nil
329+
}
330+
331+
return defaultResolver.EndpointFor(service, region, optFns...)
332+
}
333+
334+
cfg := aws.Config{
308335
Region: aws.String(region),
309336
Credentials: credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, awsSessionToken),
310337
STSRegionalEndpoint: ep,
311-
Endpoint: &endpoint,
312-
}))
338+
EndpointResolver: endpoints.ResolverFunc(stsCustResolverFn),
339+
}
340+
341+
sess := session.Must(session.NewSession(&cfg))
313342

314343
creds := stscreds.NewCredentials(sess, config.AssumeRole.RoleARN)
315344

316-
_, _ = sess.Config.Credentials.Get()
317-
_, _ = creds.Get()
318-
secretString := secretsManagerGetSecretValue(sess, &aws.Config{Credentials: creds, Region: aws.String(region)}, secret)
345+
_, err = sess.Config.Credentials.Get()
346+
if err != nil {
347+
fmt.Printf("Session get credentials error: %s", err)
348+
return *config, err
349+
}
350+
_, err = creds.Get()
351+
if err != nil {
352+
fmt.Printf("STS get credentials error: %s", err)
353+
return *config, err
354+
}
355+
secretString, err := secretsManagerGetSecretValue(sess, &aws.Config{Credentials: creds, Region: aws.String(region)}, secret)
356+
if err != nil {
357+
fmt.Printf("Get Secrets error: %s", err)
358+
return *config, err
359+
}
319360

320361
var secretData SecretData
321-
err := json.Unmarshal([]byte(secretString), &secretData)
362+
err = json.Unmarshal([]byte(secretString), &secretData)
322363
if err != nil {
323-
return *config, nil
364+
return *config, err
324365
}
366+
if secretData.PrivateKey == "" {
367+
return *config, fmt.Errorf("secret missing value for credential PrivateKey")
368+
}
369+
370+
if secretData.PublicKey == "" {
371+
return *config, fmt.Errorf("secret missing value for credential PublicKey")
372+
}
373+
325374
config.PublicKey = secretData.PublicKey
326375
config.PrivateKey = secretData.PrivateKey
327376
return *config, nil
328377
}
329378

330-
func secretsManagerGetSecretValue(sess *session.Session, creds *aws.Config, secret string) string {
379+
func secretsManagerGetSecretValue(sess *session.Session, creds *aws.Config, secret string) (string, error) {
331380
svc := secretsmanager.New(sess, creds)
332381
input := &secretsmanager.GetSecretValueInput{
333382
SecretId: aws.String(secret),
@@ -354,11 +403,11 @@ func secretsManagerGetSecretValue(sess *session.Session, creds *aws.Config, secr
354403
} else {
355404
fmt.Println(err.Error())
356405
}
357-
return ""
406+
return "", err
358407
}
359408

360409
fmt.Println(result)
361-
return *result.SecretString
410+
return *result.SecretString, err
362411
}
363412

364413
func encodeStateID(values map[string]string) string {

website/docs/index.html.markdown

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ In order to enable the Terraform MongoDB Atlas Provider with AWS SM, please foll
8888
"private_key":"secret2"
8989
}
9090
```
91-
2. Create an AWS IAM Role to attach to the AWS STS (Security Token Service) generated short lived API keys. This is required since STS generated API Keys by default have restricted permissions and need to have their permissions elevated in order to authenticate with Terraform. Take note of Role ARN and ensure IAM Role has permission for “sts:AssumeRole . For example:
91+
2. Create an AWS IAM Role to attach to the AWS STS (Security Token Service) generated short lived API keys. This is required since STS generated API Keys by default have restricted permissions and need to have their permissions elevated in order to authenticate with Terraform. Take note of Role ARN and ensure IAM Role has permission for “sts:AssumeRole”. For example:
9292
```
9393
{
9494
"Version": "2012-10-17",
@@ -102,8 +102,10 @@ In order to enable the Terraform MongoDB Atlas Provider with AWS SM, please foll
102102
"Action": "sts:AssumeRole"
103103
}
104104
]
105-
}
105+
}
106106
```
107+
In addition, you are required to also attach the AWS Managed policy of `SecretsManagerReadWrite` to this IAM role.
108+
107109
Note: this policy may be overly broad for many use cases, feel free to adjust accordingly to your organization's needs.
108110

109111
3. In terminal, store as environmental variables AWS API Keys (while you can also hardcode in config files these will then be stored as plain text in .tfstate file and should be avoided if possible). For example:
@@ -115,7 +117,7 @@ export AWS_SECRET_ACCESS_KEY="secret”
115117

116118
Note: AWS STS secrets are short lived by default, use the ` --duration-seconds` flag to specify longer duration as needed
117119

118-
5. Store each of the 3 new created secrets from AWS STS as environment variables. For example:
120+
5. Store each of the 3 new created secrets from AWS STS as environment variables (hardcoding secrets into config file with additional risk is also supported). For example:
119121
```
120122
export AWS_ACCESS_KEY_ID="ASIAYBYSK3S5FZEKLETV"
121123
export AWS_SECRET_ACCESS_KEY="lgT6kL9lr1fxM6mCEwJ33MeoJ1M6lIzgsiW23FGH"
@@ -130,6 +132,7 @@ provider "mongodbatlas" {
130132
role_arn = "arn:aws:iam::476xxx451:role/mdbsts"
131133
}
132134
secret_name = "mongodbsecret"
135+
// fully qualified secret_name ARN also supported as input "arn:aws:secretsmanager:af-south-1:553552370874:secret:test789-TO06Hy"
133136
region = "us-east-2"
134137
135138
aws_access_key_id = "ASIXXBNEK"
@@ -138,7 +141,13 @@ provider "mongodbatlas" {
138141
sts_endpoint = "https://sts.us-east-2.amazonaws.com/"
139142
}
140143
```
141-
Note: `aws_access_key_id`, `aws_secret_access_key`, and `aws_session_token` 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. Also `sts_endpoint` will be generated on behalf of user if not provider.
144+
Note: `aws_access_key_id`, `aws_secret_access_key`, and `aws_session_token` 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.
145+
146+
Note: Fully qualified `secret_name` ARN as input is REQUIRED for cross-AWS account secrets. For more detatils see:
147+
* https://aws.amazon.com/blogs/security/how-to-access-secrets-across-aws-accounts-by-attaching-resource-based-policies/
148+
* https://aws.amazon.com/premiumsupport/knowledge-center/secrets-manager-share-between-accounts/
149+
150+
Note: `sts_endpoint` parameter is REQUIRED for cross-AWS region or cross-AWS account secrets.
142151

143152
7. In terminal, `terraform init`
144153

0 commit comments

Comments
 (0)