Skip to content

Commit

Permalink
Merge pull request hashicorp#444 from lawliet89/aws-secret-role-ttl
Browse files Browse the repository at this point in the history
Add STS TTLs to `vault_aws_secret_backend_role`
  • Loading branch information
tyrannosaurus-becks committed Jul 3, 2019
2 parents a042905 + f73b88d commit f06567d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 30 deletions.
60 changes: 47 additions & 13 deletions vault/resource_aws_secret_backend_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package vault
import (
"fmt"
"log"
"strconv"
"strings"

"github.com/hashicorp/terraform/helper/schema"
Expand Down Expand Up @@ -35,7 +36,7 @@ func awsSecretBackendRoleResource() *schema.Resource {
Description: "The path of the AWS Secret Backend the role belongs to.",
},
"policy_arns": {
Type: schema.TypeList,
Type: schema.TypeSet,
Optional: true,
ConflictsWith: []string{"policy", "policy_arn", "role_arns"},
Description: "ARN for an existing IAM policy the role should use.",
Expand Down Expand Up @@ -71,7 +72,7 @@ func awsSecretBackendRoleResource() *schema.Resource {
Description: "Role credential type.",
},
"role_arns": {
Type: schema.TypeList,
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Expand All @@ -80,6 +81,18 @@ func awsSecretBackendRoleResource() *schema.Resource {
ConflictsWith: []string{"policy", "policy_arn", "policy_arns"},
Description: "ARNs of AWS roles allowed to be assumed. Only valid when credential_type is 'assumed_role'",
},
"default_sts_ttl": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "The default TTL in seconds for STS credentials. When a TTL is not specified when STS credentials are requested, and a default TTL is specified on the role, then this default TTL will be used. Valid only when credential_type is one of assumed_role or federation_token.",
},
"max_sts_ttl": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "The max allowed TTL in seconds for STS credentials (credentials TTL are capped to max_sts_ttl). Valid only when credential_type is one of assumed_role or federation_token.",
},
},
}
}
Expand All @@ -91,34 +104,31 @@ func awsSecretBackendRoleWrite(d *schema.ResourceData, meta interface{}) error {
name := d.Get("name").(string)

policyARNsIfc, ok := d.GetOk("policy_arns")
var policyARNs []string
var policyARNs []interface{}
if !ok {
policyARN := d.Get("policy_arn").(string)
policyARN := d.Get("policy_arn")
if policyARN != "" {
policyARNs = append(policyARNs, policyARN)
}
}
for _, arnIfc := range policyARNsIfc.([]interface{}) {
policyARNs = append(policyARNs, arnIfc.(string))
} else {
policyARNs = policyARNsIfc.(*schema.Set).List()
}

policy, ok := d.GetOk("policy_document")
if !ok {
policy = d.Get("policy")
}

var roleARNs []string
roleARNsIfc := d.Get("role_arns")
for _, roleIfc := range roleARNsIfc.([]interface{}) {
roleARNs = append(roleARNs, roleIfc.(string))
}
roleARNs := d.Get("role_arns").(*schema.Set).List()

if policy == "" && len(policyARNs) == 0 && len(roleARNs) == 0 {
return fmt.Errorf("either policy, policy_arns, or role_arns must be set")
}

credentialType := d.Get("credential_type").(string)

data := map[string]interface{}{
"credential_type": d.Get("credential_type").(string),
"credential_type": credentialType,
}
if policy != "" {
data["policy_document"] = policy
Expand All @@ -130,6 +140,24 @@ func awsSecretBackendRoleWrite(d *schema.ResourceData, meta interface{}) error {
data["role_arns"] = roleARNs
}

defaultStsTTL, defaultStsTTLOk := d.GetOk("default_sts_ttl")
maxStsTTL, maxStsTTLOk := d.GetOk("max_sts_ttl")
if credentialType == "assumed_role" || credentialType == "federation_token" {
if defaultStsTTLOk {
data["default_sts_ttl"] = strconv.Itoa(defaultStsTTL.(int))
}
if maxStsTTLOk {
data["max_sts_ttl"] = strconv.Itoa(maxStsTTL.(int))
}
} else {
if defaultStsTTLOk {
return fmt.Errorf("default_sts_ttl is only valid when credential_type is assumed_role or federation_token")
}
if maxStsTTLOk {
return fmt.Errorf("max_sts_ttl is only valid when credential_type is assumed_role or federation_token")
}
}

log.Printf("[DEBUG] Creating role %q on AWS backend %q", name, backend)
_, err := client.Logical().Write(backend+"/roles/"+name, data)
if err != nil {
Expand Down Expand Up @@ -180,6 +208,12 @@ func awsSecretBackendRoleRead(d *schema.ResourceData, meta interface{}) error {

d.Set("credential_type", secret.Data["credential_type"])
d.Set("role_arns", secret.Data["role_arns"])
if v, ok := secret.Data["default_sts_ttl"]; ok {
d.Set("default_sts_ttl", v)
}
if v, ok := secret.Data["max_sts_ttl"]; ok {
d.Set("max_sts_ttl", v)
}
d.Set("backend", strings.Join(pathPieces[:len(pathPieces)-2], "/"))
d.Set("name", pathPieces[len(pathPieces)-1])
return nil
Expand Down
36 changes: 21 additions & 15 deletions vault/resource_aws_secret_backend_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,34 @@ func TestAccAWSSecretBackendRole_basic(t *testing.T) {
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend),
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.0", testAccAWSSecretBackendRoleRoleArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.3970977939", testAccAWSSecretBackendRoleRoleArn_basic),
),
},
{
Config: testAccAWSSecretBackendRoleConfig_updated(name, backend, accessKey, secretKey),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "name", fmt.Sprintf("%s-policy-inline", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "default_sts_ttl", "3600"),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "max_sts_ttl", "21600"),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "backend", backend),
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend),
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.0", testAccAWSSecretBackendRoleRoleArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.2518714066", testAccAWSSecretBackendRoleRoleArn_updated),
),
},
},
Expand All @@ -84,14 +86,14 @@ func TestAccAWSSecretBackendRole_import(t *testing.T) {
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend),
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.0", testAccAWSSecretBackendRoleRoleArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.3970977939", testAccAWSSecretBackendRoleRoleArn_basic),
),
},
{
Expand Down Expand Up @@ -135,32 +137,34 @@ func TestAccAWSSecretBackendRole_nested(t *testing.T) {
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend),
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.320240204", testAccAWSSecretBackendRolePolicyArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.0", testAccAWSSecretBackendRoleRoleArn_basic),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.3970977939", testAccAWSSecretBackendRoleRoleArn_basic),
),
},
{
Config: testAccAWSSecretBackendRoleConfig_updated(name, backend, accessKey, secretKey),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "name", fmt.Sprintf("%s-policy-inline", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "default_sts_ttl", "3600"),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline", "max_sts_ttl", "21600"),
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "name", fmt.Sprintf("%s-policy-arn", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "name", fmt.Sprintf("%s-policy-inline-and-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "backend", backend),
util.TestCheckResourceAttrJSON("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_document", testAccAWSSecretBackendRolePolicyInline_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.0", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_policy_inline_and_arns", "policy_arns.1770433549", testAccAWSSecretBackendRolePolicyArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "name", fmt.Sprintf("%s-role-arns", name)),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "backend", backend),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.0", testAccAWSSecretBackendRoleRoleArn_updated),
resource.TestCheckResourceAttr("vault_aws_secret_backend_role.test_role_arns", "role_arns.2518714066", testAccAWSSecretBackendRoleRoleArn_updated),
),
},
},
Expand Down Expand Up @@ -237,6 +241,8 @@ resource "vault_aws_secret_backend_role" "test_policy_inline" {
policy_document = %q
credential_type = "assumed_role"
backend = "${vault_aws_secret_backend.test.path}"
default_sts_ttl = 3600
max_sts_ttl = 21600
}
resource "vault_aws_secret_backend_role" "test_policy_arns" {
Expand Down
14 changes: 12 additions & 2 deletions website/docs/r/aws_secret_backend_role.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,20 @@ with this role. Either `policy_document` or `policy_arns` must be specified.
is allowed to assume. Required when `credential_type` is `assumed_role` and
prohibited otherwise.

* `credential_type` - (Required) Specifies the type of credential to be used when
retrieving credentials from the role. Must be one of `iam_user`, `assumed_role`, or
* `credential_type` - (Required) Specifies the type of credential to be used when
retrieving credentials from the role. Must be one of `iam_user`, `assumed_role`, or
`federation_token`.

* `default_sts_ttl` - (Optional) The default TTL in seconds for STS credentials.
When a TTL is not specified when STS credentials are requested,
and a default TTL is specified on the role,
then this default TTL will be used. Valid only when `credential_type` is one of
`assumed_role` or `federation_token`.

* `max_sts_ttl` - (Optional) The max allowed TTL in seconds for STS credentials
(credentials TTL are capped to `max_sts_ttl`). Valid only when `credential_type` is
one of `assumed_role` or `federation_token`.

## Attributes Reference

No additional attributes are exported by this resource.
Expand Down

0 comments on commit f06567d

Please sign in to comment.