-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Add import to aws_iam_role_policy_attachment #4527
Conversation
Hello @bflad! |
Bump. Could this be merged? |
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.
Initial review below with suggestions for simplification and some explanation why I needed to mark this as a breaking change. Please reach out with any questions or if you do not have time to implement the feedback. Thanks!
@@ -43,7 +45,7 @@ func resourceAwsIamRolePolicyAttachmentCreate(d *schema.ResourceData, meta inter | |||
return fmt.Errorf("[WARN] Error attaching policy %s to IAM Role %s: %v", arn, role, err) | |||
} | |||
|
|||
d.SetId(resource.PrefixedUniqueId(fmt.Sprintf("%s-", role))) |
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.
While its unlikely that operators are currently using the ID of this resource due to its format, we do not currently have a precedent for changing the format of resource IDs and changing them is considered a major breaking change: https://www.terraform.io/docs/extend/best-practices/versioning.html#example-major-number-increments
We can support import without changing this. 👍
|
||
results := []*schema.ResourceData{} | ||
|
||
for _, policy := range resp.AttachedPolicies { |
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.
We strongly prefer to have resources only import resources 1:1 currently -- otherwise this can cause dangerous behavior if the operator is not completely vigilant after import. See also: #5631
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.
I should also note this behavior of multiple imports can be very problematic if the resources are implemented across separate modules. It will force the operator to terraform state rm
the other attachments repeatedly for each module (and likely unexpectedly).
@@ -16,6 +15,9 @@ func resourceAwsIamRolePolicyAttachment() *schema.Resource { | |||
Create: resourceAwsIamRolePolicyAttachmentCreate, | |||
Read: resourceAwsIamRolePolicyAttachmentRead, | |||
Delete: resourceAwsIamRolePolicyAttachmentDelete, | |||
Importer: &schema.ResourceImporter{ | |||
State: resourceAwsIamRolePolicyAttachmentImport, |
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.
Instead of implementing a "complex" import function (importing all attached policies), which can be dangerous, we should instead support importing the resource 1:1.
This can be implemented via (which expects a format ROLENAME_POLICYARN):
Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
idParts := strings.Split(d.Id(), "_")
if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
return nil, fmt.Errorf("unexpected format of ID (%q), expected ROLENAME_POLICYARN", d.Id())
}
roleName := idParts[0]
policyARN := idParts[1]
d.Set("policy_arn", policyARN)
d.Set("role_name", roleName)
d.SetId(resource.PrefixedUniqueId(fmt.Sprintf("%s-", roleName)))
return []*schema.ResourceData{d}, nil
},
},
And tested via:
// new function
func testAccAWSIAMRolePolicyAttachmentImportStateIdFunc(resourceName string) resource.ImportStateIdFunc {
return func(s *terraform.State) (string, error) {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return "", fmt.Errorf("not found: %s", resourceName)
}
return fmt.Sprintf("%s_%s", rs.Primary.Attributes["role_name"], rs.Primary.Attributes["policy_arn"]), nil
}
}
// As a new TestStep in TestAccAWSRolePolicyAttachment_basic
{
ResourceName: "aws_iam_role_policy_attachment.test-attach",
ImportState: true,
ImportStateIdFunc: testAccAWSIAMRolePolicyAttachmentImportStateIdFunc("aws_iam_role_policy_attachment.test-attach"),
ImportStateVerify: true,
},
Thanks for the review. I will take a look at this tonight. |
@bflad Got this working. Thanks for the review and suggestions. I don't think I have a couple questions.
Limitations on IAM Entities and Objects - AWS Identity and Access Management |
@bflad Ok. I was wrong about getting this to work. The issue here is that the create method generates a unique ID for the attachment but that ID does not contain the policy ARN. When ImportStateVerify is true the created state is compared to the imported state. Using the ImportStateIdFunc won’t help because:
Options:
I have chosen 3 as the option with the least impact. See the new PR #5910. Please let me know if you have further suggestions. |
Superseded by #5910, which has been merged and will release with version 1.37.0 of the AWS provider, likely tomorrow. 👍 |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks! |
Fixes #544
Based on @jzbruno hashicorp/terraform#12101
Changes proposed in this pull request:
Output from acceptance testing:
The test is not very robust, I had to have an empty "test-role" in my AWS account to get it to pass. Would appreciate some help on that front.