Terraform-provider-aws: aws_guardduty_member says it needs to be recreated if done via organization

Created on 23 Jun 2020  路  4Comments  路  Source: hashicorp/terraform-provider-aws

Community Note

  • Please vote on this issue by adding a 馃憤 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform Version

0.12.26

Affected Resource(s)

  • aws_guardduty_member

Terraform Configuration Files

# In an organization infrastructure account, which we designated as the GuardDuty admin account:
resource "aws_guardduty_detector" "main" {
  enable = true
}

resource "aws_guardduty_organization_configuration" "main" {
  auto_enable = true
  detector_id = aws_guardduty_detector.main.id
}

resource "aws_guardduty_member" "trussworks_sandbox" {
   account_id                 = local.trussworks_sandbox_id
   detector_id                = aws_guardduty_detector.main.id
   email                      = local.trussworks_sandbox_email
   invite                     = false
   disable_email_notification = true
}

In this case, trussworks_sandbox is an account we created before we enabled GuardDuty, so it was not automatically added a member automatically via the auto_enable in aws_guardduty_organization_configuration.

No GuardDuty resources are configured in the trussworks_sandbox account because GuardDuty appears to create the detector automatically when it is added as a member.

Expected Behavior

Running Terraform with this code should create the member, and then subsequent runs should say no changes are necessary because the membership is already created.

Actual Behavior

Running Terraform once with this code successfully created the membership, as expected. However, on subsequent terraform apply executions, it attempts to recreate the resource:

  # aws_guardduty_member.trussworks_sandbox must be replaced
-/+ resource "aws_guardduty_member" "trussworks_sandbox" {
        account_id                 = "REDACTED"
        detector_id                = "REDACTED"
        disable_email_notification = true
      + email                      = "[email protected]" # forces replacement
      ~ id                         = "REDACTED" -> (known after apply)
      ~ invite                     = true -> false
      ~ relationship_status        = "Enabled" -> (known after apply)
    }

Steps to Reproduce

  1. Create an AWS organization with three accounts -- a "master" account, the GuardDuty admin account, and another account.
  2. Make the GuardDuty admin account the GuardDuty admin account (...obviously), and configure as above.
  3. Add the third account as a GuardDuty member with the code above.
  4. Run terraform apply, and then run terraform apply again.
servicguardduty upstream

Most helpful comment

A possible workaround for now is to ignore email address changes. However from my tests one would still need to set invite to true as well, even though it is not necessary from an API point of view when being in an AWS organization. But terraform somehow stores always true in the state which seem to be a bug with organizations as well.

resource "aws_guardduty_member" "member" {
  invite = true
  lifecycle {
    ignore_changes = [
      email
    ]
  }
}

All 4 comments

I experienced this issue last week and found that calling get-members and list-members using the AWS CLI returned the members correctly but with no email address in the responses (even though it's documented as required).
This explains why terraform continuously tries to re-create the resource as the state never reflects what is returned from the API.

I raised a GuardDuty Technical AWS support ticket and walked them through the issue and it appears there is a difference in behaviour between using email invitations (when the email is returned) and using AWS Organisations (when email is not returned).

The technical support person has now raised this with the GuardDuty team to find out it's a mistake or expected behaviour that requires updates to API documentation.

In the meantime to avoid this I've added added the Organisation Master account as a member of the delegated account outside of terraform and ensured auto-enable is turned on so that all other accounts do not require the aws_guardduty_member resource blocks anyway. Once this is fixed I will add the member block back for the Organisation master account and do an import.

A possible workaround for now is to ignore email address changes. However from my tests one would still need to set invite to true as well, even though it is not necessary from an API point of view when being in an AWS organization. But terraform somehow stores always true in the state which seem to be a bug with organizations as well.

resource "aws_guardduty_member" "member" {
  invite = true
  lifecycle {
    ignore_changes = [
      email
    ]
  }
}

Just a quick update, AWS Support confirmed through the GuardDuty team the following:

This is an expected behavior. If customer is using organization, we do not rely on the email address provided using GD create-members, since there is no guardduty invite flow we do not use it ( we rely on AWS Organization for validation) and we do not not validate the email address provided using create-members. So it is possible that customer can provide incorrect email address for create-members. So basically we dont want provide email address to get-members and list-members which master can get it from AWS Organization describe-account or AWS Organization list-accounts API.

They are looking at updating documentation to reflect this but could give no timelines.

Is there possible discussion anywhere on updating the resource definition to not require email? Or setting the resource up to accept an org argument in place of email?

Was this page helpful?
0 / 5 - 0 ratings