hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.81k stars 9.16k forks source link

Return accounts for aws_organizations_organization data source when accessing through delegated administrator account #16595

Open foxylion opened 3 years ago

foxylion commented 3 years ago

Community Note

Description

When having set-up the Organization with AWS Control Tower a separate "audit" account is created. This account is also allowed to access the organization details like the list of accounts.

I would expect the aws_organizations_organization data source to return a list of accounts if the permissions of the current user in the account is sufficient.

This is useful to configure e.g. GuardDuty in the audit account. There you need a list of all accounts to invite them as members. (see example below)

New or Affected Resource(s)

Potential Terraform Configuration

data "aws_organizations_organization" "default" {}

resource "aws_guardduty_member" "members" {
  for_each    = data.aws_organizations_organization.default.accounts
  detector_id = aws_guardduty_detector.default.id
  account_id  = each.value.Id
  email       = each.value.Email
}
ejohn20 commented 3 years ago

I was able to work around this using different providers and modules for the org and audit accounts.

In the module for the org account:

resource "aws_organizations_organization" "default" {
  feature_set = "ALL"

  aws_service_access_principals = [
    "cloudtrail.amazonaws.com",
    "config.amazonaws.com",
    "ram.amazonaws.com",
    "guardduty.amazonaws.com",
  ]

  enabled_policy_types = [
    "SERVICE_CONTROL_POLICY"
  ]
}

resource "aws_guardduty_organization_admin_account" "default" {
  depends_on = [aws_organizations_organization.default]

  admin_account_id = var.audit_account_id
}

output "organization_accounts" {
    description = "List of organization accounts."
    value = aws_organizations_organization.default.accounts
}

In the main.tf file

module "organization" {
  source = "./live/organization"

  providers = {
    aws = aws
  }
}

module "audit" {
  depends_on = [module.organization]
  source     = "./live/audit"

  providers = {
    aws = aws.audit
  }
 ...
 organization_accounts = module.organization.organization_accounts
}

In the module for the audit account:

variable "organization_accounts" {
  description = "List of organization accounts."
  type = list(map(any))
}

resource "aws_guardduty_member" "member" {
  for_each = {
    for account in var.organization_accounts : account.id => account
    if account.id != var.audit_account_id
  }
  detector_id = aws_guardduty_detector.default.id
  account_id  = each.value.id
  email = each.value.email
}
apicht commented 3 years ago

I just ran into this as well. Multiple provider workaround doesn't work for us due to the way we are using Terragrunt. It appears there is a guard to prevent querying the account list if not operating from the master.

Offending line: https://github.com/hashicorp/terraform-provider-aws/blob/9efd68d6ccb4e812d5be5d98447939fb6a635d47/aws/data_source_aws_organizations_organization.go#L159