Untitled

mail@pastecode.io avatar
unknown
plain_text
13 days ago
5.0 kB
2
Indexable
Never
import os
import yaml
from aws_cdk import aws_iam as iam, App, Stack, Tags
from principal_environment import PrincipalEnvironment
from stacks.stack import SeaEpamCurationStack


class Main:
    def __init__(self) -> None:
        self.physical_environments = ["dev", "staging", "prod"]
        self.create_app()

    def create_app(self) -> None:
        app = App()

        env = self.__create_environment()
        default_tags, interfaces = self.__get_config()
        stacks = []

        for interface in interfaces:
            if interface.get("name"):
                deploy_environments = interface.get(
                    "environments", self.physical_environments
                )
                if not deploy_environments or env.aws_environment_name not in deploy_environments:
                    continue

                stacks.extend(self.__create_resources(interface, app, env, default_tags))

        self.apply_permissions_boundary(env, stacks)

        app.synth()

    @staticmethod
    def apply_permissions_boundary(
        env: PrincipalEnvironment, stacks: list[Stack]
    ) -> None:
        for stack in stacks:
            permissions_boundary = iam.ManagedPolicy.from_managed_policy_arn(
                stack,
                "application_permissions_boundary",
                f"arn:aws:iam::{env.account}:policy/pfg/infra/pfg-app-role-boundary",
            )
            iam.PermissionsBoundary.of(stack).apply(permissions_boundary)

    @staticmethod
    def __create_environment() -> PrincipalEnvironment:
        account = os.environ["AWS_ACCOUNT_ID"]
        region = os.environ["AWS_REGION"]
        primary_region = os.environ["AWS_PRIMARY_REGION"]
        secondary_region = os.environ["AWS_SECONDARY_REGION"]
        aws_environment_name = os.environ["AWS_ENVIRONMENT"]
        return PrincipalEnvironment(
            account=account,
            account_alias="prinam-my-fa",
            region=region,
            primary_region=primary_region,
            secondary_region=secondary_region,
            aws_environment_name=aws_environment_name,
        )

    @staticmethod
    def __get_config() -> tuple[dict, list]:
        interfaces = []
        with open("./config/common.yaml", "r", encoding="utf-8") as config_file:
            config = yaml.safe_load(config_file)
            interfaces.append(config)

        for file in os.listdir("./config/data_sources"):
            with open(
                f"./config/data_sources/{file}", "r", encoding="utf-8"
            ) as config_file:
                interfaces.append(yaml.safe_load(config_file))

        default_tags = config.get("default_tags")
        return default_tags, interfaces

    @staticmethod
    def __get_virtual_environments() -> list[dict[str, str]]:
        aws_environment = os.environ.get("AWS_ENVIRONMENT", "dev")

        with open("./environments.yaml", "r", encoding="utf-8") as config_file:
            environments_config = yaml.safe_load(config_file)

        return environments_config.get(aws_environment)

    def __get_app_name(self, interface_name: str, virtual_environment_name: str) -> str:
        app_name = f"{interface_name}-{virtual_environment_name}"

        if virtual_environment_name not in self.physical_environments:
            app_name = f"prinam-my-fa-{interface_name}-{virtual_environment_name}"

        return app_name

    @staticmethod
    def __add_tags(stack: Stack, custom_tags: dict) -> None:
        for key, value in custom_tags.items():
            Tags.of(stack).add(
                key=key, value=value, priority=None, apply_to_launched_instances=True
            )

    def __create_resources(
        self, config: dict, app: App, env: PrincipalEnvironment, default_tags: dict
    ) -> list[SeaEpamCurationStack]:

        env_stacks = []
        virtual_environments = self.__get_virtual_environments()

        for virtual_environment in virtual_environments:
            virtual_environment_name = virtual_environment["name"]
            stack_name = self.__get_app_name(config["name"], virtual_environment_name)

            current_stack = SeaEpamCurationStack(
                app,
                f"{stack_name}",
                env=env,
                interface_config=config
            )

            current_tags = default_tags | config.get("custom_tags", {})

            # Deployment will fail if no app inventory ID is provided, as the stack execution role won't have
            # access to all the necessary permissions
            if not current_tags.get("pfg-app-inventory-id"):
                raise ValueError("App Inventory ID required for deployment")

            self.__add_tags(current_stack, current_tags)
            env_stacks.append(current_stack)

        return env_stacks


if __name__ == "__main__":
    Main()
Leave a Comment