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?