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/aws: Delete access keys before deleting IAM user #7766

Merged
merged 5 commits into from
Jul 25, 2016
Merged

provider/aws: Delete access keys before deleting IAM user #7766

merged 5 commits into from
Jul 25, 2016

Conversation

dtolnay
Copy link
Contributor

@dtolnay dtolnay commented Jul 21, 2016

Without this change:

Error deleting IAM User my-user: DeleteConflict: Cannot delete entity, must delete access keys first.

We add access keys outside of Terraform because we do not want the secret keys in the tfstate.

@radeksimko
Copy link
Member

Hi @dtolnay
thank you for the PR. I understand the intentions here - cleaning up manually created keys. That's a valid use case 👍

One of the core Terraform's principles is to not destroy/change things it doesn't manage however. It's sometimes hard to decide what is actually being managed - i.e. just user or user and their keys, but if keys can be managed separately via Terraform I think it's very clear that it should be that resource responsible for management of keys:
https://www.terraform.io/docs/providers/aws/r/iam_access_key.html

The current behaviour with the current schema is as intended - i.e. Terraform should error out if there are existing access keys that are managed outside of Terraform. It is possible that they just simply manage the keys elsewhere and they forgot to delete those - these keys may potentially be in use and the user may want to verify that.

We can however let users opt in to the destructive behaviour via special field, e.g. force_destroy = true (defaults to false). See how we do this in aws_s3_bucket

Would you mind making the behaviour opt-in - i.e. explicit rather than implicit?


I saw that piece of code responsible for detaching the user from IAM Groups - and I suggest we treat that as a bug which will need to be fixed at some point. Generally speaking if Terraform is deleting/changing something outside the scope of a given resource, it's most likely (exceptions apply) a bug that should be reported and/or fixed.

@radeksimko radeksimko added the waiting-response An issue/pull request is waiting for a response from the community label Jul 22, 2016
@dtolnay
Copy link
Contributor Author

dtolnay commented Jul 22, 2016

Makes sense, thanks for the feedback. I added a force_destroy option to control removal of non-Terraform-managed access keys.

@radeksimko radeksimko removed the waiting-response An issue/pull request is waiting for a response from the community label Jul 22, 2016
@@ -173,6 +184,16 @@ func resourceAwsIamUserDelete(d *schema.ResourceData, meta interface{}) error {
}
}

for _, k := range accessKeys {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind moving this for loop along with var accessKeys []string into the force_destroy condition too?
It IMO makes sense from the context point of view.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 done

*marker = *r.Marker
}
*truncated = *r.IsTruncated
return true
Copy link
Member

@radeksimko radeksimko Jul 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this going to loop forever if shouldContinue = true? Shouldn't this be something like

if !lastPage {
  return true
}

or possibly return !lastPage?

The previous implementation used ListGroupsForUserOutput.IsTruncated to make decisions when paginating. I don't mind you changing the implementation as long as the behaviour remains the same. Can you confirm the behaviour is exactly the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did confirm that the ListAccessKeysPages function is smart about not looping forever. My account is limited to 2 access keys per user so I set MaxItems to 1, changed this line to return false and confirmed that only 1 access key was deleted, then changed this line to return true and confirmed that both access keys were deleted (and it did not loop forever).

I have not tested ListGroupsForUserPages specifically but it goes through the same codepath. I can test later today or I can change it back if you prefer.

The shouldContinue is really only for iterating over a limited number of pages or searching for something until you find it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed both to return !lastPage for clarity.

@radeksimko
Copy link
Member

I will have a look into how the pagination works in AWS SDK to verify it works as expected and we don't end up in endless loop or something like that. 😃 Your implementation may be completely correct - I just haven't seen that one anywhere else.

Otherwise this is looking pretty good - just one small thing I'd like to ask you for - can you document this new field in https://github.com/hashicorp/terraform/blob/master/website/source/docs/providers/aws/r/iam_user.html.markdown ?

Thanks.

@radeksimko radeksimko self-assigned this Jul 22, 2016
@dtolnay
Copy link
Contributor Author

dtolnay commented Jul 22, 2016

I added force_destroy to the website.

@radeksimko
Copy link
Member

I have looked at the implementation of EachPage function in the SDK to confirm that our assumptions were correct here. It also explains why return true (i.e. shouldContinue = true) won't cause endless loop. That function won't be called at all if there are no pages to iterate over. That said return !isLastPage is IMO cleaner.

Thanks. 👍

@radeksimko radeksimko merged commit ad62f09 into hashicorp:master Jul 25, 2016
robinbowes added a commit to yo61/terraform that referenced this pull request Jul 25, 2016
* master: (34 commits)
  Update CHANGELOG.md
  provider/aws: Delete access keys before deleting IAM user (hashicorp#7766)
  Fix broken link to Consul demo (hashicorp#7789)
  provider/aws: `aws_redshift_cluster` `number_of_nodes` was having the (hashicorp#7771)
  provider/aws: Restore lost client.simpledbconn initialization
  Update vendored atlas client
  Make using `ssl_verify_mode` more robust (hashicorp#7769)
  Update CHANGELOG.md
  provider/aws: Rename the ECS Container Data Source test
  docs/azure: Small changes to remove the use of double
  Update docs to centralize on ARM-based Azure provider (hashicorp#7767)
  Update CHANGELOG.md
  Update CHANGELOG.md
  Add support for Kinesis streams shard-level metrics (hashicorp#7684)
  Update CHANGELOG.md
  Implementing aws_ami_launch_permission. (hashicorp#7365)
  Update CHANGELOG.md
  Add VersionString
  provider/aws: Set `storage_encrypted` to state in (hashicorp#7751)
  provider/fastly: Update go-fastly SDK (hashicorp#7747)
  ...
@dtolnay dtolnay deleted the delkeys branch July 25, 2016 14:23
@ghost
Copy link

ghost commented Apr 24, 2020

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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants