How to get formatted string of account id’s from aws_organizations_organization

Using Terraform v1.0.0.

Trying to source the non_master_accounts ids list from a data organizations_organization resource to build a formatted list, but always getting it won’t be known until apply. I don’t know how to work around this. The end goal is to deploy a Cloudformation stackset to deploy a unified cloudtrail trail and S3 bucket in a specified account.

resource "aws_cloudformation_stack_set" "unified_cloudtrail_trail" {
  auto_deployment {
    enabled = true
  }
  name         = "unified-cloudtrail-trail"
  description  = "A CloudFormation stackset that configures the a Cloudtrail trail and a S3 bucket to enable use of an account as a target account for unifying cloudtrail logs"
  capabilities = []

  parameters = {
    "UnifiedCloudtrailAccounts" = formatlist("arn:aws:cloudtrail:*:%s:trail/audit-events", data.aws_organizations_organization.ktl.non_master_accounts[*].id)
  }

  permission_model = "SELF_MANAGED"
  template_body    = file("${path.module}/stacksets/unified_cloudtrail.yml")

  lifecycle {
    ignore_changes = [parameters, administration_role_arn]
  }

  tags = {
    "Provisioner" = "cloudformation"
    "ManagedBy"   = "stackset"
  }
}
Terraform v1.0.0
on linux_amd64
Configuring remote state backend...
Initializing Terraform configuration...
╷
│ Error: Incorrect attribute value type
│
│   on stacksets.tf line 60, in resource "aws_cloudformation_stack_set" "unified_cloudtrail_trail":
│   60:   parameters = {
│   61:     "UnifiedCloudtrailAccounts" = formatlist("arn:aws:cloudtrail:*:%s:trail/audit-events", data.aws_organizations_organization.ktl.non_master_accounts[*].id)
│   62:   }
│     ├────────────────
│     │ data.aws_organizations_organization.ktl.non_master_accounts will be known only after apply
│
│ Inappropriate value for attribute "parameters": element
│ "UnifiedCloudtrailAccounts": string required.

Hi @alberto.lopez,

I’m not really familiar with this resource type, but the error message here seems to be saying that this element is expected to be just a single string, and so the result of formatlist cannot be assigned to it. (That function always returns a list of strings.)

Perhaps in order to pass a list there you will need to first encode it into a string representation of the list. For example, you could use jsonencode to serialize it as a JSON array, or you could use join to concatenate all of the values together with a delimiter that doesn’t otherwise appear in any of the values. Which of these would be appropriate will depend on the expectations of whatever will be making use of this value, of course.

1 Like

That did the trick, thanks!!

  parameters = {
    "UnifiedCloudtrailAccounts" = join(",",formatlist("arn:aws:cloudtrail:*:%s:trail/audit-events", data.aws_organizations_organization.ktl.non_master_accounts[*].id))
  }
1 Like