public addUser()

in core/src/notebook-platform/notebook-platform.ts [325:446]


  public addUser(userList: NotebookUserOptions []) {
    //Initialize the managedEndpointArns
    //Used to store the arn of managed endpoints after creation for each users
    //This is used to update the IAM policy
    let managedEndpointArns: string [] = [];
    //let managedEndpointObjects: Map<string, CustomResource> = new Map <string, CustomResource> ();

    let iamRolePolicy: ManagedPolicy;

    let iamUserList: string [] = [];

    //Loop through each user and create its managed endpoint(s) as defined by the user
    for (let user of userList) {

      //For each policy create a role and then pass it to addManageEndpoint to create an endpoint
      user.notebookManagedEndpoints.forEach( (notebookManagedEndpoint, index) => {

        //Check if the managedendpoint is already used in role which is created for a managed endpoint
        //if there is no managedendpointArn create a new managedendpoint
        //else get managedendpoint and push it to  @managedEndpointArns
        if (!this.managedEndpointExecutionPolicyArnMapping.has(notebookManagedEndpoint.executionPolicy.managedPolicyName)) {

          //For each user or group, create a new managedEndpoint
          //ManagedEndpoint ARN is used to update and scope the session policy of the user or group

          let emrOnEksVersion: string | undefined = user.notebookManagedEndpoints[index].emrOnEksVersion;
          let configOverride: string | undefined = user.notebookManagedEndpoints[index].configurationOverrides;

          let managedEndpoint = this.emrEks.addManagedEndpoint(
            this,
            `${this.studioName}${Utils.stringSanitizer(notebookManagedEndpoint.executionPolicy.managedPolicyName)}`,
            {
              managedEndpointName: `${this.studioName}-${notebookManagedEndpoint.executionPolicy.managedPolicyName}`,
              virtualClusterId: this.emrVirtCluster.attrId,
              executionRole: this.emrEks.createExecutionRole(
                this,
                `${user.identityName}${index}`,
                notebookManagedEndpoint.executionPolicy,
              ),
              emrOnEksVersion: emrOnEksVersion ? emrOnEksVersion : undefined,
              configurationOverrides: configOverride ? configOverride : undefined,
            },

          );

          managedEndpoint.node.addDependency(this.emrEks);

          //Get the Security Group of the ManagedEndpoint which is the Engine Security Group
          let engineSecurityGroup: ISecurityGroup = SecurityGroup.fromSecurityGroupId(
            this,
            `engineSecurityGroup${user.identityName}${index}`,
            managedEndpoint.getAttString('securityGroup'));

          Tags.of(engineSecurityGroup).add('for-use-by-analytics-reference-architecture', 'true');

          let vpcCidrBlock: string = this.emrEks.eksCluster.vpc.vpcCidrBlock;

          //Update workspace Security Group to allow outbound traffic on port 18888 toward Engine Security Group
          this.workSpaceSecurityGroup.addEgressRule(Peer.ipv4(vpcCidrBlock), Port.tcp(18888), 'Allow traffic to EMR');

          this.engineSecurityGroup?.addIngressRule(Peer.ipv4(vpcCidrBlock), Port.tcp(18888), 'Allow traffic from EMR Studio');

          this.workSpaceSecurityGroup.applyRemovalPolicy(RemovalPolicy.DESTROY);

          //Tag the Security Group of the ManagedEndpoint to be used with EMR Studio
          Tags.of(engineSecurityGroup).add('for-use-with-amazon-emr-managed-policies', 'true');

          //Add the managedendpointArn to @managedEndpointExcutionPolicyArnMapping
          //This is to avoid the creation an endpoint with the same policy twice
          //Save resources and reduce the deployment time
          // TODO check the emr version is the same => to be fixed on a later commit need to solve adding a tuple to a JS map
          this.managedEndpointExecutionPolicyArnMapping.set(notebookManagedEndpoint.executionPolicy.managedPolicyName, managedEndpoint.getAttString('arn'));

          //Push the managedendpoint arn to be used in to build the policy to attach to it
          managedEndpointArns.push(managedEndpoint.getAttString('arn'));
        } else {
          let managedPolicyName = notebookManagedEndpoint.executionPolicy.managedPolicyName;
          managedEndpointArns.push(<string> this.managedEndpointExecutionPolicyArnMapping.get(managedPolicyName));
        }
      });

      if (this.authMode === 'IAM' && this.federatedIdPARN === undefined) {
        //Create the role policy and gets its ARN
        iamRolePolicy = createIAMRolePolicy(this, user, this.studioServiceRole.roleName,
          managedEndpointArns, this.studioId);

        let iamUserCredentials: string = createIAMUser(this, iamRolePolicy!, user.identityName);

        if (this.nestedStackParent != undefined) {
          new CfnOutput(this.nestedStackParent, `${user.identityName}`, {
            value: iamUserCredentials,
          });
        }

      } else if (this.authMode === 'IAM' && this.federatedIdPARN != undefined) {
        //Create the role policy and gets its ARN
        iamRolePolicy = createIAMRolePolicy(this, user, this.studioServiceRole.roleName,
          managedEndpointArns, this.studioId);

        createIAMFederatedRole(this, iamRolePolicy!, this.federatedIdPARN!, user.identityName, this.studioId);

      } else if (this.authMode === 'SSO') {
        //Create the session policy and gets its ARN
        let sessionPolicyArn = createUserSessionPolicy(this, user, this.studioServiceRole.roleName,
          managedEndpointArns, this.studioId);

        if (user.identityType == 'USER' || user.identityType == 'GROUP') {
          //Map a session to user or group
          new CfnStudioSessionMapping(this, 'studioUser' + user.identityName + user.identityName, {
            identityName: user.identityName,
            identityType: user.identityType,
            sessionPolicyArn: sessionPolicyArn,
            studioId: this.studioId,
          });
        } else {
          throw new Error(`identityType should be either USER or GROUP not ${user.identityType}`);
        }
      }
    }

    return iamUserList;
  }