From ba2a8c256a69afc660716e157cfa503fed8c1eef Mon Sep 17 00:00:00 2001 From: "Audun V. Nes" Date: Thu, 12 Sep 2024 10:19:02 +0200 Subject: [PATCH] Add sub module to manage sharing through AWS Resource Manager and use it (#1539) to share IPAM pools --- _sub/security/org-account-query/main.tf | 3 +++ _sub/security/org-account-query/outputs.tf | 3 +++ _sub/security/org-account-query/vars.tf | 4 +++ _sub/security/org-account-query/versions.tf | 10 +++++++ _sub/security/org-account-query/versions.tofu | 9 +++++++ _sub/security/resource-access-manager/main.tf | 21 +++++++++++++++ _sub/security/resource-access-manager/vars.tf | 22 +++++++++++++++ .../resource-access-manager/versions.tf | 10 +++++++ .../resource-access-manager/versions.tofu | 10 +++++++ network/ipam/main.tf | 25 +++++++++++++++++ network/ipam/vars.tf | 27 +++++++++++++++++++ 11 files changed, 144 insertions(+) create mode 100644 _sub/security/org-account-query/main.tf create mode 100644 _sub/security/org-account-query/outputs.tf create mode 100644 _sub/security/org-account-query/vars.tf create mode 100644 _sub/security/org-account-query/versions.tf create mode 100644 _sub/security/org-account-query/versions.tofu create mode 100644 _sub/security/resource-access-manager/main.tf create mode 100644 _sub/security/resource-access-manager/vars.tf create mode 100644 _sub/security/resource-access-manager/versions.tf create mode 100644 _sub/security/resource-access-manager/versions.tofu diff --git a/_sub/security/org-account-query/main.tf b/_sub/security/org-account-query/main.tf new file mode 100644 index 000000000..fd3cdca2b --- /dev/null +++ b/_sub/security/org-account-query/main.tf @@ -0,0 +1,3 @@ +data "aws_organizations_organizational_unit_child_accounts" "this" { + parent_id = var.ou_id +} diff --git a/_sub/security/org-account-query/outputs.tf b/_sub/security/org-account-query/outputs.tf new file mode 100644 index 000000000..7df0fba04 --- /dev/null +++ b/_sub/security/org-account-query/outputs.tf @@ -0,0 +1,3 @@ +output "account_ids" { + value = [for account in data.aws_organizations_organizational_unit_child_accounts.this.accounts : account.id] +} diff --git a/_sub/security/org-account-query/vars.tf b/_sub/security/org-account-query/vars.tf new file mode 100644 index 000000000..e413ea4b2 --- /dev/null +++ b/_sub/security/org-account-query/vars.tf @@ -0,0 +1,4 @@ +variable "ou_id" { + type = string + description = "The ID of the AWS Organization OU that you want to query for accounts." +} diff --git a/_sub/security/org-account-query/versions.tf b/_sub/security/org-account-query/versions.tf new file mode 100644 index 000000000..8b0a39707 --- /dev/null +++ b/_sub/security/org-account-query/versions.tf @@ -0,0 +1,10 @@ + +terraform { + required_version = ">= 1.3.0, < 1.6.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.66.0" + } + } +} diff --git a/_sub/security/org-account-query/versions.tofu b/_sub/security/org-account-query/versions.tofu new file mode 100644 index 000000000..2d5162a5d --- /dev/null +++ b/_sub/security/org-account-query/versions.tofu @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.8.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.66.0" + } + } +} diff --git a/_sub/security/resource-access-manager/main.tf b/_sub/security/resource-access-manager/main.tf new file mode 100644 index 000000000..84109f43f --- /dev/null +++ b/_sub/security/resource-access-manager/main.tf @@ -0,0 +1,21 @@ +locals { + all_tags = merge(var.tags, { "Name" = var.resource_share_name }) +} + +resource "aws_ram_resource_share" "this" { + name = var.resource_share_name + allow_external_principals = false // Allow only accounts within the organization to access the resource share + tags = local.all_tags +} + +resource "aws_ram_resource_association" "this" { + for_each = toset(var.resource_arns) + resource_share_arn = aws_ram_resource_share.this.arn + resource_arn = each.value +} + +resource "aws_ram_principal_association" "this" { + for_each = toset(var.principals) + resource_share_arn = aws_ram_resource_share.this.arn + principal = each.value +} diff --git a/_sub/security/resource-access-manager/vars.tf b/_sub/security/resource-access-manager/vars.tf new file mode 100644 index 000000000..867b7eb9a --- /dev/null +++ b/_sub/security/resource-access-manager/vars.tf @@ -0,0 +1,22 @@ +variable "resource_share_name" { + type = string + description = "The name of the RAM resource share" +} + +variable "resource_arns" { + type = list(string) + description = "The ARNs of the resource to share" + default = [] +} + +variable "principals" { + type = list(string) + description = "The ARNs of the principals to associate with the resource share" + default = [] +} + +variable "tags" { + type = map(string) + description = "A map of tags to apply to all the resources deployed by the module" + default = {} +} diff --git a/_sub/security/resource-access-manager/versions.tf b/_sub/security/resource-access-manager/versions.tf new file mode 100644 index 000000000..0ddcaaa88 --- /dev/null +++ b/_sub/security/resource-access-manager/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.3.0, < 1.6.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.66.0" + } + } +} diff --git a/_sub/security/resource-access-manager/versions.tofu b/_sub/security/resource-access-manager/versions.tofu new file mode 100644 index 000000000..9f1337780 --- /dev/null +++ b/_sub/security/resource-access-manager/versions.tofu @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.8.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.66.0" + } + } +} diff --git a/network/ipam/main.tf b/network/ipam/main.tf index 90318360f..4038cdcd4 100644 --- a/network/ipam/main.tf +++ b/network/ipam/main.tf @@ -85,3 +85,28 @@ module "regional_capabilities_pools" { source_ipam_pool_id = module.capabilities_pool.id tags = var.tags } + +module "org-account-query" { + source = "../../_sub/security/org-account-query" + ou_id = var.ipam_ou_id +} + +module "ram_share_with_platform" { + source = "../../_sub/security/resource-access-manager" + resource_share_name = length(var.ipam_prefix) > 0 ? "ipam-${var.ipam_prefix}-platform" : "ipam-platform" + resource_arns = [ + for pool in values(module.regional_platform_pools) : pool.arn + ] + principals = var.ipam_platform_principals + tags = var.tags +} + +module "ram_share_with_capabilities" { + source = "../../_sub/security/resource-access-manager" + resource_share_name = length(var.ipam_prefix) > 0 ? "ipam-${var.ipam_prefix}-capabilities" : "ipam-capabilities" + resource_arns = [ + for pool in values(module.regional_capabilities_pools) : pool.arn + ] + principals = formatlist(var.ipam_role_pattern, module.org-account-query.account_ids, var.ipam_role_name) + tags = var.tags +} diff --git a/network/ipam/vars.tf b/network/ipam/vars.tf index 976aa8ee7..25079ec02 100644 --- a/network/ipam/vars.tf +++ b/network/ipam/vars.tf @@ -76,6 +76,33 @@ variable "ipam_prefix" { default = "" } +variable "ipam_platform_principals" { + type = list(string) + description = "The ARNs of the principals to associate with a Resource Manager share for the regional platform pools" + default = [] +} + +variable "ipam_ou_id" { + type = string + description = "The ID of the AWS Organization OU that you want to query for accounts. This is used for sharing access to the IPAM pools." +} + +variable "ipam_role_name" { + type = string + description = "The name of an IAM role in each AWS Organization account that is allowed to request IP addresses from the IPAM pools." + default = "AWSServiceRoleForIPAM" +} + +variable "ipam_role_pattern" { + type = string + description = <