Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider: add assume_role.0.duration and deprecate assume_role.0.duration_seconds #23077

Merged
merged 10 commits into from
Feb 10, 2022
7 changes: 7 additions & 0 deletions .changelog/23077.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:note
provider: The `assume_role.duration_seconds` argument has been deprecated. All configurations using `assume_role.duration_seconds` should be updated to use the new `assume_role.duration` argument instead.
```

```release-note:enhancement
provider: Add `duration` argument to the `assume_role` configuration block
```
22 changes: 18 additions & 4 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1936,11 +1936,20 @@ func assumeRoleSchema() *schema.Schema {
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,
Description: "The duration, in seconds, of the role session.",
ValidateFunc: validation.IntBetween(900, 43200),
Type: schema.TypeInt,
Optional: true,
Deprecated: "Use assume_role.0.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,
Expand Down Expand Up @@ -2022,6 +2031,11 @@ func endpointsSchema() *schema.Schema {
func expandAssumeRole(m map[string]interface{}) *awsbase.AssumeRole {
assumeRole := awsbase.AssumeRole{}

if v, ok := m["duration"].(string); ok && v != "" {
duration, _ := time.ParseDuration(v)
assumeRole.Duration = duration
}

if v, ok := m["duration_seconds"].(int); ok && v != 0 {
assumeRole.Duration = time.Duration(v) * time.Second
}
Expand Down
23 changes: 23 additions & 0 deletions internal/provider/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package provider

import (
"fmt"
"time"
)

// 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
}
68 changes: 68 additions & 0 deletions internal/provider/validate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package provider

import (
"regexp"
"testing"
)

func TestValidAssumeRoleDuration(t *testing.T) {
testCases := []struct {
val interface{}
expectedErr *regexp.Regexp
}{
{
val: "",
expectedErr: regexp.MustCompile(`cannot be parsed as a duration`),
},
{
val: "1",
expectedErr: regexp.MustCompile(`cannot be parsed as a duration`),
},
{
val: "10m",
expectedErr: regexp.MustCompile(`must be between 15 minutes \(15m\) and 12 hours \(12h\)`),
},
{
val: "12h30m",
expectedErr: regexp.MustCompile(`must be between 15 minutes \(15m\) and 12 hours \(12h\)`),
},
{

val: "15m",
},
{
val: "1h10m10s",
},
{

val: "12h",
},
}

matchErr := func(errs []error, r *regexp.Regexp) bool {
// err must match one provided
for _, err := range errs {
if r.MatchString(err.Error()) {
return true
}
}

return false
}

for i, tc := range testCases {
_, errs := ValidAssumeRoleDuration(tc.val, "test_property")

if len(errs) == 0 && tc.expectedErr == nil {
continue
}

if len(errs) != 0 && tc.expectedErr == nil {
t.Fatalf("expected test case %d to produce no errors, got %v", i, errs)
}

if !matchErr(errs, tc.expectedErr) {
t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs)
}
}
}
1 change: 1 addition & 0 deletions website/docs/guides/version-4-upgrade.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ provider "aws" {

Version 4.0.0 adds these new provider arguments:

* `assume_role.duration` - The assume role duration represented as a string e.g. `"1h"` or `"1h30s"`. Replaces `assume_role.duration_seconds`, which has been deprecated in Terraform AWS Provider v4.0.0 and support will be removed in a future version.
* `ec2_metadata_service_endpoint` - Address of the EC2 metadata service (IMDS) endpoint to use. Can also be set with the `AWS_EC2_METADATA_SERVICE_ENDPOINT` environment variable.
* `ec2_metadata_service_endpoint_mode` - Mode to use in communicating with the metadata service. Valid values are `IPv4` and `IPv6`. Can also be set with the `AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE` environment variable.
* `s3_use_path_style` - Replaces `s3_force_path_style`, which has been deprecated in Terraform AWS Provider v4.0.0 and support will be removed in a future version.
Expand Down
3 changes: 2 additions & 1 deletion website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ In addition to [generic `provider` arguments](https://www.terraform.io/docs/conf

The `assume_role` configuration block supports the following optional arguments:

* `duration_seconds` - (Optional) Number of seconds to restrict the assume role session duration. You can provide a value from 900 seconds (15 minutes) up to the maximum session duration setting for the role.
* `duration` - (Optional, Conflicts with `duration_seconds`) Duration of the assume role session. You can provide a value from 15 minutes up to the maximum session duration setting for the role. Represented by a string such as `1h`, `2h45m`, or `30m15s`.
* `duration_seconds` - (Optional, **Deprecated** use `duration` instead) Number of seconds to restrict the assume role session duration. You can provide a value from 900 seconds (15 minutes) up to the maximum session duration setting for the role.
* `external_id` - (Optional) External identifier to use when assuming the role.
* `policy` - (Optional) IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.
* `policy_arns` - (Optional) Set of Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.
Expand Down