Hey all.
I have the following code:
from constructs import Construct
from cdktf import TerraformStack, TerraformOutput, Token, Fn, TerraformLocal
from cdktf_cdktf_provider_aws.provider import AwsProvider
from cdktf_cdktf_provider_aws.data_aws_organizations_organization import DataAwsOrganizationsOrganization
from cdktf_cdktf_provider_aws.data_aws_eks_clusters import DataAwsEksClusters
class DiscoveryStackConfig:
aws_profile: str
shared_config_files: list = None
shared_credentials_files: list = None
def __init__(self, aws_profile: str, shared_config_files: list = None, shared_credentials_files: list = None):
self.aws_profile = aws_profile
self.shared_config_files = shared_config_files
self.shared_credentials_files = shared_credentials_files
class DiscoveryModuleStack(TerraformStack):
def __init__(self, scope: Construct, name: str, config: DiscoveryStackConfig):
super().__init__(scope, name)
# Default AWS shared config and credentials files
shared_config_files = ["~/.aws/config"] if config.shared_config_files is None else config.shared_config_files
shared_credentials_files = [
"~/.aws/config"] if config.shared_credentials_files is None else config.shared_credentials_files
# Management account AWS provider definition
AwsProvider(self, "management-account-provider", profile=config.aws_profile,
shared_config_files=shared_config_files, shared_credentials_files=shared_credentials_files)
organization = DataAwsOrganizationsOrganization(self, "organization")
accounts = Token.as_list(organization.accounts)
TerraformOutput(self, "accounts", value=accounts)
for idx, account in enumerate(accounts):
account_id = Fn.lookup(Fn.element(accounts, idx), "id", "")
TerraformOutput(self, f"account_{idx}", value=Fn.lookup(Fn.element(accounts, idx), "id", ""))
account_provider = AwsProvider(self, f"aws.{idx}", profile=account_id, alias=f"_{idx}",
shared_config_files=shared_config_files,
shared_credentials_files=shared_credentials_files)
clusters = DataAwsEksClusters(self, f"clusters_{idx}", provider=account_provider)
TerraformOutput(self, f"clusters_output_{idx}", value=clusters)
First, I’m listing the accounts in an AWS Organization, then in each account, I’d like to list the EKS clusters.
Since each account requires a different AwsProvider definition (because provider block in Terraform doesn’t support count or for_each), I’m using Python for loop to iterate over the accounts list that is produced by the DataAwsOrganizationsOrganization data source, and create AwsProvider in each iteration.
I then use the account ID in the profile argument of AwsProvider (my AWS config file has the account IDs as the profile names).
I have 2 accounts in said accounts list, as can be seen in the TerraformOutput identified as accounts:
accounts = tolist([
{
"arn" = "arn:aws:organizations::222222222222:account/o-1234567890/111111111111"
"email" = "linked1@a.com"
"id" = "111111111111"
"name" = "linked1"
"status" = "ACTIVE"
},
{
"arn" = "arn:aws:organizations::222222222222:account/o-1234567890/222222222222"
"email" = "payer@a.com"
"id" = "222222222222"
"name" = "payer"
"status" = "ACTIVE"
},
])
However, when I iterate over the accounts list from DataAwsOrganizationsOrganization, only one of my 2 accounts is iterated over, as can be seen in the TerraformOutput identified as account_{idx}:
account_0 = "222222222222"
When printing the accounts Python variable (which is the one I’m iterating over), I see a list with only one element:
['#{TfToken[TOKEN.14]}']
Is there any reason that when iterating over the accounts list that is produced by DataAwsOrganizationsOrganization, using Python for loop, only the first element is extracted, as opposed to using the same list as TerraformOutput, which shows 2 elements?
Is there a way to use Python for loop to iterate over a list that is produced by a data source?