How to create and use ServiceAccounts in python code

Hi all,

This is my first topic on the platform, thus I would like to apologize if I do not follow correct format in writing topic.

My environment:

  • cdktf 0.15.0
  • python 3.10.9
  • terraform 1.3.7

The goal:
I’m trying to create confluent api keys with service accounts from the dictionary. The dictionary is format users = {“username1”: {<some_config>}, “username2”: {<some_config>},…}

The problem:
I wanto to iterate over the list of users, to create service accounts and for each service account to create one api key. I’d appreciate any idea on how to do it?

Pseudo code:

from typing import Dict, Any

from constructs import Construct
from cdktf import TerraformStack, TerraformLocal, TerraformIterator, Token

from imports.confluent.service_account import ServiceAccount
from imports.confluent.api_key import ApiKey


class TestStack(TerraformStack):
    def __init__(self, scope: Construct, id: str,
                 users: Dict[str, Any]):
        super().__init__(scope, id)

        users = TerraformLocal(self, "users", expression=users)
        iter = TerraformIterator.from_map(users.as_any_map)

        service_account = ServiceAccount(self, id_="service_accounts",
                                         display_name=Token.as_string(iter.key),
                                         description=f"Service Account for user {Token.as_string(iter.key)}",
                                         for_each=iter)

        # service_account.for_each is MapTerraformIterator
        
        sa_itr = service_account.for_each

        api_key = ApiKey(self, id_="api_keys",
                         owner={
                             "id": Token.as_string(sa_itr.id),
                             "api_version": Token.as_string(sa_itr.api_version),
                             "kind": Token.as_string(sa_itr.kind)
                         },
                         display_name=Token.as_string(sa_itr.key),
                         for_each=sa_itr,
                         depends_on=[service_account])

The error message is that MapTerraformIterator doesn’t have properties id, api_version and kind.

I would appreciate any idea on how to accomplish this.

P.S. I’ve tried also to override for_each in api_key, but I don’t know how to format the output from ServiceAccount.

Hi @gsmiljanic :wave: Welcome!

Is the users dictionary available in Python? If yes, you could also use Python code to loop over the Entries in that object and create multiple ServiceAccount and ApiKey instances – something you couldn’t do in Terraform but can in CDKTF.

If the dictionary is only available when Terraform runs (e.g. because its values are coming from a data source, e.g. from a remote state data source), you’d have to keep using TerraformIterators or the escape hatch, if you are running into limitations with the Iterator. There is currently an open issue in regards to basing an iterator on another iterator: Support accessing resources created by an iterator · Issue #2024 · hashicorp/terraform-cdk · GitHub

Hi @ansgarm .

Thank you for your response and answer. I was able to fix the issue by using Python loop to create the resources.

Thank you.