From 70e671ee2136e9116f6cc4a50ee0de38d05d109d Mon Sep 17 00:00:00 2001 From: Kurtis Mash <24705116+kurtismash@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:53:43 +0100 Subject: [PATCH] Fix CloudFormation StackSet creation when deployed to the management account --- main.tf | 20 +++++++++++--------- modules/service-deployment/cloudformation.tf | 5 +++-- modules/service-deployment/variables.tf | 1 + 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/main.tf b/main.tf index 4bddcc9..a31eada 100644 --- a/main.tf +++ b/main.tf @@ -1,10 +1,11 @@ locals { # Internal - account_id = data.aws_caller_identity.current.account_id - organization_id = data.aws_organizations_organization.org.id - partition_id = data.aws_partition.current.partition - region = data.aws_region.current.region - deployment_regions = [local.region] + account_id = data.aws_caller_identity.current.account_id + organization_id = data.aws_organizations_organization.org.id + organization_management_account_id = data.aws_organizations_organization.org.master_account_id + partition_id = data.aws_partition.current.partition + region = data.aws_region.current.region + deployment_regions = [local.region] # Member account deployment role names are templated here but used throughout this module and submodules. member_account_deployment_helper_role_name_template = "${var.member_account_resource_name_prefix}-deployment-helper-" @@ -40,10 +41,11 @@ module "deployment" { retained_vaults = each.value.retained_vaults current = { - account_id = local.account_id - organization_id = local.organization_id - partition = local.partition_id - region = local.region + account_id = local.account_id + organization_id = local.organization_id + organization_management_account_id = local.organization_management_account_id + partition = local.partition_id + region = local.region } central_account_resource_name_prefix = var.central_account_resource_name_prefix central_backup_service_linked_role_arn = local.backup_service_linked_role_arn diff --git a/modules/service-deployment/cloudformation.tf b/modules/service-deployment/cloudformation.tf index e01f108..9bd71ea 100644 --- a/modules/service-deployment/cloudformation.tf +++ b/modules/service-deployment/cloudformation.tf @@ -5,6 +5,7 @@ locals { [for i in var.admin_role_names : { "Fn::Sub" : "arn:$${AWS::Partition}:iam::$${AWS::AccountId}:role/${i}" }], { "Ref" : "CentralBackupServiceRoleArn" } ]) + cfn_call_as = var.current.organization_management_account_id == var.current.account_id ? "SELF" : "DELEGATED_ADMIN" } resource "aws_cloudformation_stack_set" "member_account_deployments" { @@ -12,7 +13,7 @@ resource "aws_cloudformation_stack_set" "member_account_deployments" { description = "Centralised AWS Backup for ${var.service_name}." capabilities = ["CAPABILITY_NAMED_IAM"] permission_model = "SERVICE_MANAGED" - call_as = "DELEGATED_ADMIN" + call_as = local.cfn_call_as # Try to do as much as possible in native CloudFormation, but some things, like dynamic lists, are only possible in Terraform. # jsonencode(jsondecode(...)) used to minify the file. @@ -60,7 +61,7 @@ resource "aws_cloudformation_stack_set" "member_account_deployments" { resource "aws_cloudformation_stack_instances" "member_account_deployments" { stack_set_name = aws_cloudformation_stack_set.member_account_deployments.name - call_as = "DELEGATED_ADMIN" + call_as = local.cfn_call_as regions = var.deployment_regions deployment_targets { organizational_unit_ids = var.deployment_targets diff --git a/modules/service-deployment/variables.tf b/modules/service-deployment/variables.tf index d4270cd..5a9868c 100644 --- a/modules/service-deployment/variables.tf +++ b/modules/service-deployment/variables.tf @@ -49,6 +49,7 @@ variable "current" { type = object({ account_id : string organization_id : string + organization_management_account_id : string partition : string region : string })