-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
d/aws_iam_session_context: New data source #19957
Changes from 21 commits
d86a246
b81de6a
11d04ce
c659b64
62d7c93
984d0cd
4ecde63
f887951
ad1f9a3
ae63556
1125604
3353636
1cdcdf2
8394cf0
914cd83
39f176a
a4704cc
1a02f96
8abcda5
074ec4e
c096125
aa4183c
3f2f55b
4947200
8c76c24
1232685
db6575b
a824e7c
4252de0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-data-source | ||
aws_iam_assumed_role_source | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
|
||
"github.com/aws/aws-sdk-go/aws/arn" | ||
"github.com/aws/aws-sdk-go/service/iam" | ||
"github.com/hashicorp/aws-sdk-go-base/tfawserr" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/finder" | ||
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/waiter" | ||
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" | ||
) | ||
|
||
func dataSourceAwsIAMAssumedRoleSource() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceAwsIAMAssumedRoleSourceRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"arn": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ewbankkit marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
"role_path": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"role_name": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"source_arn": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"session_name": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceAwsIAMAssumedRoleSourceRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).iamconn | ||
|
||
arn := d.Get("arn").(string) | ||
|
||
d.SetId(arn) | ||
|
||
roleName := "" | ||
sessionName := "" | ||
var err error | ||
|
||
if roleName, sessionName = roleNameSessionFromARN(arn); roleName == "" { | ||
d.Set("source_arn", arn) | ||
d.Set("session_name", "") | ||
d.Set("role_name", "") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The field name structure for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the challenge here is if you're using an IAM user, you should still be able to get out a passed through user ARN from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I see what you are saying. Don't love it, but can't think of a better way to do it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
d.Set("role_path", "") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think returning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed. |
||
|
||
return nil | ||
} | ||
|
||
var role *iam.Role | ||
|
||
err = resource.Retry(waiter.PropagationTimeout, func() *resource.RetryError { | ||
var err error | ||
|
||
role, err = finder.RoleByName(conn, roleName) | ||
|
||
if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) { | ||
return resource.RetryableError(err) | ||
} | ||
|
||
if err != nil { | ||
return resource.NonRetryableError(err) | ||
} | ||
|
||
return nil | ||
}) | ||
|
||
if tfresource.TimedOut(err) { | ||
role, err = finder.RoleByName(conn, roleName) | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("unable to get role (%s): %w", roleName, err) | ||
} | ||
|
||
if role == nil || role.Arn == nil { | ||
return fmt.Errorf("empty role returned (%s)", roleName) | ||
} | ||
|
||
d.Set("session_name", sessionName) | ||
d.Set("role_name", roleName) | ||
d.Set("source_arn", role.Arn) | ||
d.Set("role_path", role.Path) | ||
|
||
return nil | ||
} | ||
|
||
// roleNameSessionFromARN returns the role and session names in an ARN if any. | ||
// Otherwise, it returns empty strings. | ||
func roleNameSessionFromARN(rawARN string) (string, string) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function would ideally return an error if there is no session name to grab (i.e. its not a valid sts assumed-role arn), right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the problem is that good Go says we should return an error if we don't plan on dealing with it, which we don't. |
||
parsedARN, err := arn.Parse(rawARN) | ||
|
||
if err != nil { | ||
return "", "" | ||
} | ||
|
||
parts := strings.Split(parsedARN.Resource, "/") | ||
|
||
reAssume := regexp.MustCompile(`^assumed-role/.{1,}/.{2,}`) | ||
reRole := regexp.MustCompile(`^role/.{1,}`) | ||
|
||
if reAssume.MatchString(parsedARN.Resource) && parsedARN.Service != "sts" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, IIRC there are enums for the service names? (sts and iam) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't use the sts enum but can do the iam. Avoiding import of multiple services. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, dependency for just an enum is not worth it. Go principle: little copying is better than a little dependency. |
||
return "", "" | ||
} | ||
|
||
if reRole.MatchString(parsedARN.Resource) && parsedARN.Service != "iam" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My take on this is we should spit IAM role ARNs out just like we would any non-sts assumed-role ARN. If they want metadata on a role, they should use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we have the role name, I figure I'd also verify IAM role - no cost. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its not costly, but I think it muddies the water a little on what this data source does. Its easiest to say if you pass in an assumed-role arn we'll give you back all of the metadata and if not you only get sourceArn. Once you add in a case for IAM role, I think the use case isn't quite as clear. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I can see that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Water un muddied |
||
return "", "" | ||
} | ||
|
||
if !reAssume.MatchString(parsedARN.Resource) && !reRole.MatchString(parsedARN.Resource) { | ||
return "", "" | ||
} | ||
|
||
if reRole.MatchString(parsedARN.Resource) && len(parts) > 1 { | ||
return parts[len(parts)-1], "" | ||
} | ||
|
||
if len(parts) < 3 { | ||
return "", "" | ||
} | ||
|
||
return parts[len(parts)-2], parts[len(parts)-1] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.