Skip to content

nationalarchives/terraform-aws-organizations-ous-by-path

Repository files navigation

Terraform module: AWS Organizations OUs by path

An open-source Terraform module to create and/or expose AWS Organizations Organizational Units with their paths from the Organization root.

  • Can be used as a resource or data source with the same outputs.
  • Supports up to 5 levels of Organizational Units (AWS Quota).
  • Define your organization structure as a map.
  • Generates OrgPaths, to be used with the aws:PrincipalOrgPaths and aws:ResourceOrgPaths IAM conditions.
  • Organizational Units are exposed via a list and indexed maps, see Outputs for more information.

Each OU is represented as a map with attributes
  • arn - ARN of the OU.
  • child_accounts - List of AWS accounts that are direct children of the OU. Dependent upon the include_child_accounts variable.
    • arn - ARN of the account.
    • email - Email of the account.
    • id - Identifier of the account.
    • name - Name of the account.
  • descendant_accounts - List of AWS accounts that are direct children or descendants of the OU. Dependent upon the include_descendant_accounts variable.
    • arn - ARN of the account.
    • email - Email of the account.
    • id - Identifier of the account.
    • name - Name of the account.
  • id - ID of the OU.
  • name - Name of the OU.
  • name_path - Path to the OU using OU names, delimited by the name_path_delimiter variable.
  • org_path - Path to the OU from the Organization ID, to be used with the aws:PrincipalOrgPaths and aws:ResourceOrgPaths IAM conditions.
  • parent_id - ID of the OU's direct parent.

Usage

As a resource

module "ous" {
  source = "nationalarchives/organizations-ous-by-path/aws"
  # It's recommended to explicitly constrain the acceptable version numbers to avoid unexpected or unwanted changes.

  organization_structure = {
    "Level 1 OU" = {
      "Level 2 OU" = {
        "Level 3 OU" = {
          "Level 4 OU" = {
            "Level 5 OU"   = {},
            "Level 5 OU-2" = {}
          }
        }
      }
    },
    "Level 1 OU-2" = {}
  }
}

data "aws_iam_policy_document" "scp" {
  statement {
    effect    = "Allow"
    actions   = ["*"]
    resources = ["*"]
  }
}
resource "aws_organizations_policy" "scp" {
  name    = "SCP"
  content = data.aws_iam_policy_document.scp.json
}
resource "aws_organizations_policy_attachment" "scp" {
  policy_id = aws_organizations_policy.scp.id
  target_id = module.ous.by_name_path["Level 1 OU/Level 2 OU/Level 3 OU"].id
}

As a data source

module "ous" {
  source = "nationalarchives/organizations-ous-by-path/aws"
  # It's recommended to explicitly constrain the acceptable version numbers to avoid unexpected or unwanted changes.
}

# Create a bucket and allow access from accounts within a specified OU.
data "aws_iam_policy_document" "bucket_policy" {
  statement {
    principals {
      type        = "AWS"
      identifiers = ["*"]
    }
    actions = [
      "s3:GetObject",
      "s3:ListBucket",
    ]
    resources = [
      aws_s3_bucket.bucket.arn,
      "${aws_s3_bucket.bucket.arn}/*",
    ]
    condition {
      test     = "ForAllValues:StringEquals"
      variable = "aws:PrincipalOrgPaths"
      values   = [module.ous.by_name_path["Level 1 OU/Level 2 OU"].org_path]
    }
  }
}
resource "aws_s3_bucket" "bucket" {
  bucket_prefix = "bucket-"
}
resource "aws_s3_bucket_policy" "allow_access_from_another_account" {
  bucket = aws_s3_bucket.bucket.id
  policy = data.aws_iam_policy_document.bucket_policy.json
}

Requirements

Name Version
terraform >= 1.10.0
aws >= 4.55.0

Providers

No providers.

Modules

Name Source Version
data ./modules/data n/a
resource ./modules/resource n/a

Resources

No resources.

Inputs

Name Description Type Default Required
include_child_accounts Include direct child AWS accounts in the output, increases the number of API calls when enabled. bool false no
include_descendant_accounts Include descendant AWS accounts in the output, increases complexity when enabled. bool false no
name_path_delimiter Delimiter used to join names in the name_path attribute of each OU. string "/" no
organization_structure The structure of OUs to manage as a map of maps. If not provided, this module will function as a data source. any {} no

Outputs

Name Description
by_id Map of OUs indexed by id.
by_name_path Map of OUs indexed by name_path.
list List of OUs with added attributes name_path and org_path.

About The National Archives, UK

We are a non-ministerial department, and the official archive and publisher for the UK Government, and for England and Wales. We are the guardians of over 1,000 years of iconic national documents.

We are expert advisers in information and records management and are a cultural, academic and heritage institution. We fulfil a leadership role for the archive sector and work to secure the future of physical and digital records.

Find out more about what we do.