Kinda curious what others are doing but I am wonde...
# aws
s
Kinda curious what others are doing but I am wondering how much you guys are using the conf file for your environments? I have a bunch of stuff in my conf file for each environment and I am thinking about pulling some of it back into the main.py (Python) file instead. Still playing with options but curious what others are doing? I come from a heavy Terraform (tfvars) world so putting a lot of the environment-specific info in the conf file makes sense.
f
I've got a single shared config file and a wrapper script that always selects that config file. Then I have a code based config class, and an instance of that class for each stack. The entrypoint takes the stack name as an arg and grabs the appropriate config object at runtime
s
Would love to see what you are doing of you can share.
f
yeah, lemme do a bit of sanitization. We're using pulumi to set up multi-account workloads within an AWS account. each workload has a pipeline account, 0-n dev accounts, 0-n prod accounts. We're using control tower to create the accounts, the using pulumi to customize them doing stuff like: • creating cross account roles from the pipeline account -> environment accounts • creating workload scoped gitlab groups + repos w/ protected branches and approval rules • adding gitlab runners in the pipeline accounts which have access to the deployment roles • setting up cross account dns delegation We have a workload registry that looks like this
Copy code
class WorkloadRegistry:
    workloads: Dict[str, WorkloadConfig] = {}

    @staticmethod
    def register(workload: WorkloadConfig):
        if workload.name in WorkloadRegistry.workloads:
            raise ValueError(f"Workload '{workload.name}' already registered")
        WorkloadRegistry.workloads[workload.name] = workload

    @staticmethod
    def get(workload_name: str) -> WorkloadConfig:
        if workload_name not in WorkloadRegistry.workloads:
            raise ValueError(f"Workload '{workload_name} has not been registered")
        return WorkloadRegistry.workloads[workload_name]
Workload definitions look like this:
Copy code
@dataclass
class Environment:
    name: str
    """The name of the environment."""
    domains: List[str] = field(default_factory=lambda: [])
    """The list of domains associated with the account."""


@dataclass
class WorkloadConfig:
    name: str
    """The name of the workload."""

    gitlab_notifications_slack_channel: Optional[str]
    """
    The name of the slack channel that gitlab slack notifications should be routed to.

    Requires that @gitlab-notifications has been added to the channel.
    """
    protected_branches: List[str]
    """The list of branches to protect for the workload."""
    projects: List[str]
    """A list of GitLab project to create for the workload."""

    admins: List[str] = field(default_factory=lambda: [])
    """
    A list of users who are privileged users within the workload to add new developers/owners.
    """
    admin_permission_sets: List[str] = field(
        default_factory=lambda: ["xxx"]
    )
    """
    A list of permission sets that workload privileged users are given.
    """
    
    developers: List[str] = field(default_factory=lambda: [])
    """
    A list <first name>.<last name> of developers to grant access for the workload.
    """
    prod_environments: List[Environment] = field(
        default_factory=lambda: [Environment("production")]
    )

    dev_environments: List[Environment] = field(
        default_factory=lambda: [Environment("development")]
    )
And then we define the config objects and add them to the registry
Copy code
WorkloadRegistry.register(
    WorkloadConfig(
        "sample-workload",
        gitlab_notifications_slack_channel="#team-sample-workload",
        projects=["sample-workload-app", "sample-workload-iac"],
        protected_branches=[
            "development",
            "production",
        ],
        dev_environments=[
            Environment(
                "development",
                domains=[
                    "<http://dev.whatever.com|dev.whatever.com>",
                ],
            ),
            Environment("demo", domains=["<http://demo.whatever.com|demo.whatever.com>"]),
        ],
        prod_environments=[
            Environment("production", domains=["<http://prod.whatever.com|prod.whatever.com>"]),
        ],
        developers=[
            "andrew.fitzgerald",
        ],
    )
)
s
Wow okay let me see if I can start digesting this.
f
basically just a giant map of <stack-name> -> <stack-config-objects>
b
@freezing-van-87649 unrelated, but I am just about done with a controltower provider that will allow you to kcik off the control tower process directly from pulumi. is that of interest?
f
absolutely
batch account creation is a pita
user experience is not great
s
Actually created a complete process of "vending" accounts at work. Created this before control tower was a thing but I would like to see more for sure. @billowy-army-68599
👍 1
b
@billowy-army-68599 are you planning on publishing the Control Tower provider?
b
hit a snag with it, so will be coming back to it
👍 1
b
Thanks - I need to set up our account structure so thought I might give it a try if it was available.
a
@billowy-army-68599 just following this thread. I will be curious to give that provider a try when it's ready. Planning to use pulumi to help with automatic creation/setup of multiple accounts if possible.