Repository: linz/geostore

Issue:
Infra: add permissions for other AWS account users to launch API endpoint Lambda functions
Add permissions for other AWS account users to launch API endpoint Lambda functions.

Allow following accounts: 
* Data Services 
* Topo


Discussion:

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -12,6 +12,7 @@
 from datalake.processing_stack import ProcessingStack
 from datalake.staging_stack import StagingStack
 from datalake.storage_stack import StorageStack
+from datalake.users_stack import UsersStack
 
 ENVIRONMENT_TYPE_TAG_NAME = "EnvironmentType"
 ENV = environ.get("DEPLOY_ENV", "dev")
@@ -31,6 +32,13 @@ def main():
 
     app = core.App()
 
+    users = UsersStack(
+        app,
+        "users",
+        stack_name=f"geospatial-data-lake-users-{ENV}",
+        env={"region": region, "account": account},
+    )
+
     networking = NetworkingStack(
         app,
         "networking",
@@ -63,6 +71,7 @@ def main():
         stack_name=f"geospatial-data-lake-api-{ENV}",
         env={"region": region, "account": account},
         datasets_table=storage.datasets_table,
+        users_role=users.users_role,
     )
 
     StagingStack(
diff --git a/datalake/api_stack.py b/datalake/api_stack.py
--- a/datalake/api_stack.py
+++ b/datalake/api_stack.py
@@ -8,7 +8,14 @@
 class APIStack(core.Stack):
     """Data Lake stack definition."""
 
-    def __init__(self, scope: core.Construct, stack_id: str, datasets_table, **kwargs) -> None:
+    def __init__(
+        self,
+        scope: core.Construct,
+        stack_id: str,
+        datasets_table,
+        users_role,
+        **kwargs,
+    ) -> None:
         super().__init__(scope, stack_id, **kwargs)
 
         ############################################################################################
@@ -34,6 +41,8 @@ def __init__(self, scope: core.Construct, stack_id: str, datasets_table, **kwarg
                 ),
             )
 
+            endpoint_function.grant_invoke(users_role)
+
             datasets_table.grant_read_write_data(endpoint_function)
             datasets_table.grant(
                 endpoint_function, "dynamodb:DescribeTable"
diff --git a/datalake/users_stack.py b/datalake/users_stack.py
new file mode 100644
--- /dev/null
+++ b/datalake/users_stack.py
@@ -0,0 +1,27 @@
+import os
+
+from aws_cdk import aws_iam, core
+from aws_cdk.core import Duration, Tags
+
+
+class UsersStack(core.Stack):
+    def __init__(self, scope: core.Construct, stack_id: str, **kwargs) -> None:
+        super().__init__(scope, stack_id, **kwargs)
+
+        account_ids = (
+            aws_iam.AccountPrincipal(account_id=account_id)
+            for account_id in os.environ.get(
+                "DATALAKE_USERS_AWS_ACCOUNTS_IDS", aws_iam.AccountRootPrincipal().account_id
+            ).split(",")
+        )
+
+        principals = aws_iam.CompositePrincipal(*account_ids)
+
+        self.users_role = aws_iam.Role(
+            self,
+            "users-role",
+            assumed_by=principals,
+            max_session_duration=Duration.hours(12),
+        )
+
+        Tags.of(self.users_role).add("ApplicationLayer", "users")


Test patch: