private createSageMakerWritePolicies()

in packages/constructs/L3/ai/datascience-team-l3-construct/lib/datascience-team-l3-construct.ts [400:976]


  private createSageMakerWritePolicies(teamBucket: IBucket, teamKey: IKey, teamExecutionRole: IRole): ManagedPolicy[] {
    //We use two write policies in order to avoid policy length limits within IAM
    const sagemakerWriteManagedPolicy1 = new MdaaManagedPolicy(this, 'ex-write-managed-pol', {
      managedPolicyName: this.props.team.verbatimPolicyNamePrefix
        ? this.props.team.verbatimPolicyNamePrefix + '-' + 'sm-write'
        : 'sm-write',
      verbatimPolicyName: this.props.team.verbatimPolicyNamePrefix != undefined,
      naming: this.props.naming,
    });

    //We use two write policies in order to avoid policy length limits within IAM
    //New statements should be added
    const sagemakerWriteManagedPolicy2 = new MdaaManagedPolicy(this, 'sm-write-managed-pol2', {
      managedPolicyName: this.props.team.verbatimPolicyNamePrefix
        ? this.props.team.verbatimPolicyNamePrefix + '-' + 'sm-write-2'
        : 'sm-write-2',
      verbatimPolicyName: this.props.team.verbatimPolicyNamePrefix != undefined,
      naming: this.props.naming,
    });

    //Allow passing of team execution role to sagemaker jobs, etc
    const teamRoleStatement = new PolicyStatement({
      sid: 'TeamRole',
      effect: Effect.ALLOW,
      resources: [teamExecutionRole.roleArn],
      actions: ['iam:PassRole'],
    });
    sagemakerWriteManagedPolicy1.addStatements(teamRoleStatement);

    //Allow SageMaker permissions required to be used as execution role for Jobs
    const sagemakerJobStatement = new PolicyStatement({
      sid: 'CreateandManageJobs',
      effect: Effect.ALLOW,
      resources: [
        `arn:${this.partition}:sagemaker:${this.region}:${this.account}:*job/*`,
        `arn:${this.partition}:sagemaker:${this.region}:${this.account}:*job-definition/*`,
      ],
      actions: [
        'sagemaker:Create*Job',
        'sagemaker:Create*JobDefinition',
        'sagemaker:Delete*JobDefinition',
        'sagemaker:Update*Job',
        'sagemaker:Stop*Job',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerJobStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for Jobs not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [
            `Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:*job/*`,
            `Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:*job-definition/*`,
          ],
        },
      ],
      true,
    );
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Actions scoped for job management permissions, taking into account policy length limits. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [
            `Action::sagemaker:Create*Job`,
            `Action::sagemaker:Create*JobDefinition`,
            `Action::sagemaker:Delete*JobDefinition`,
            `Action::sagemaker:Delete*Job`,
            `Action::sagemaker:Update*Job`,
            `Action::sagemaker:Stop*Job`,
          ],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to be used as execution role for Model Monitoring Schedules
    const sagemakerModelMonitoringStatement = new PolicyStatement({
      sid: 'CreateandManageModelMonitoring',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:monitoring-schedule/*`],
      actions: [
        'sagemaker:CreateMonitoringSchedule',
        'sagemaker:UpdateMonitoringSchedule',
        'sagemaker:DeleteMonitoringSchedule',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerModelMonitoringStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for monitoring schedules not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:monitoring-schedule/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create and manage model cards
    const sagemakerModelCardStatement = new PolicyStatement({
      sid: 'CreateandManageModelCards',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:model-card/*`],
      actions: ['sagemaker:CreateModelCard', 'sagemaker:DeleteModelCard', 'sagemaker:UpdateModelCard'],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerModelCardStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for model cards not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:model-card/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to be used as execution role for Pipelines
    const sagemakerPipelineStatement = new PolicyStatement({
      sid: 'CreateandManagePipelines',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:pipeline/*`],
      actions: [
        'sagemaker:CreatePipeline',
        'sagemaker:DeletePipeline',
        'sagemaker:RetryPipelineExecution',
        'sagemaker:StartPipelineExecution',
        'sagemaker:StopPipelineExecution',
        'sagemaker:SendPipelineExecutionStepSuccess',
        'sagemaker:SendPipelineExecutionStepFailure',
        'sagemaker:UpdatePipeline',
        'sagemaker:UpdatePipelineExecution',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerPipelineStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for Pipelines not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:pipeline/*`],
        },
      ],
      true,
    );
    //Allow SageMaker permissions required to create and manage models
    const sagemakerModelStatement = new PolicyStatement({
      sid: 'CreateAndManageModels',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:model/*`],
      actions: ['sagemaker:CreateModel', 'sagemaker:DeleteModel'],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerModelStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for Models not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:model/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create and manage models
    const sagemakerModelPackageStatement = new PolicyStatement({
      sid: 'CreateAndManageModelPackages',
      effect: Effect.ALLOW,
      resources: [
        `arn:${this.partition}:sagemaker:${this.region}:${this.account}:model-package/*`,
        `arn:${this.partition}:sagemaker:${this.region}:${this.account}:model-package-group/*`,
      ],
      actions: [
        'sagemaker:CreateModelPackage',
        'sagemaker:DeleteModelPackage',
        'sagemaker:UpdateModelPackage',
        'sagemaker:BatchDescribeModelPackage',
        'sagemaker:CreateModelPackageGroup',
        'sagemaker:DeleteModelPackageGroup',
        'sagemaker:DeleteModelPackageGroupPolicy',
        'sagemaker:PutModelPackageGroupPolicy',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerModelPackageStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for model packages not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [
            `Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:model-package/*`,
            `Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:model-package-group/*`,
          ],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create and manage projects
    const sagemakerProjectStatement = new PolicyStatement({
      sid: 'CreateAndManageProjects',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:project/*`],
      actions: ['sagemaker:CreateProject', 'sagemaker:DeleteProject', 'sagemaker:UpdateProject'],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerProjectStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for Projects not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:project/*`],
        },
      ],
      true,
    );

    //Allow usage of Team KMS key for creating notebook instances
    const sagemakerKmsStatement = new PolicyStatement({
      sid: 'SageMakerKmsAccess',
      effect: Effect.ALLOW,
      resources: [teamKey.keyArn],
      actions: ['kms:CreateGrant'],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerKmsStatement);

    //Allow SageMaker permissions required to create and manage endpoints
    const sagemakerEndpointStatement = new PolicyStatement({
      sid: 'CreateAndManageEndpoints',
      effect: Effect.ALLOW,
      resources: [
        `arn:${this.partition}:sagemaker:${this.region}:${this.account}:endpoint/*`,
        `arn:${this.partition}:sagemaker:${this.region}:${this.account}:endpoint-config/*`,
      ],
      actions: [
        'sagemaker:CreateEndpoint',
        'sagemaker:DeleteEndpoint',
        'sagemaker:UpdateEndpoint',
        'sagemaker:UpdateEndpointWeightsAndCapacities',
        'sagemaker:CreateEndpointConfig',
        'sagemaker:DeleteEndpointConfig',
        'sagemaker:InvokeEndpoint',
        'sagemaker:InvokeEndpointAsync',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerEndpointStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for endpoints are not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [
            `Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:endpoint/*`,
            `Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:endpoint-config/*`,
          ],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create and manage trials
    const sagemakerTrialStatement = new PolicyStatement({
      sid: 'CreateAndManageTrials',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:experiment*`],
      actions: [
        'sagemaker:CreateTrial',
        'sagemaker:CreateTrialComponent',
        'sagemaker:AssociateTrialComponent',
        'sagemaker:DisassociateTrialComponent',
        'sagemaker:DeleteTrial',
        'sagemaker:DeleteTrialComponent',
        'sagemaker:UpdateTrial',
        'sagemaker:UpdateTrialComponent',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerTrialStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for experiments are not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:experiment*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create and manage notebooks
    const sagemakerNotebookStatement = new PolicyStatement({
      sid: 'CreateAndManageNotebooks',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:notebook-instance/*`],
      actions: [
        'sagemaker:CreateNotebookInstance',
        'sagemaker:UpdateNotebookInstance',
        'sagemaker:DeleteNotebookInstance',
        'sagemaker:StartNotebookInstance',
        'sagemaker:StopNotebookInstance',
        'sagemaker:CreatePresignedNotebookInstanceUrl',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerNotebookStatement);

    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for Notebook Instances not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:notebook-instance/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create and manage notebooks
    const sagemakerNotebookLifecycleStatement = new PolicyStatement({
      sid: 'CreateAndManageNotebookLifecycles',
      effect: Effect.ALLOW,
      resources: [
        `arn:${this.partition}:sagemaker:${this.region}:${this.account}:notebook-instance-lifecycle-config/*`,
      ],
      actions: [
        'sagemaker:CreateNotebookInstanceLifecycleConfig',
        'sagemaker:UpdateNotebookInstanceLifecycleConfig',
        'sagemaker:DeleteNotebookInstanceLifecycleConfig',
      ],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerNotebookLifecycleStatement);

    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for Notebook Lifecycle Configs not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [
            `Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:notebook-instance-lifecycle-config/*`,
          ],
        },
      ],
      true,
    );

    // Allow access to put records to feature groups
    const sagemakerPutRecordFeatureGroupStatement = new PolicyStatement({
      sid: 'PutRecordFeatureGroups',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:feature-group/*`],
      actions: ['sagemaker:PutRecord', 'sagemaker:DeleteRecord'],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerPutRecordFeatureGroupStatement);

    //Allow SageMaker permissions required to create online feature-groups
    //Must be encrypted with team key
    const sagemakerCreateOnlineFeatureGroupStatement = new PolicyStatement({
      sid: 'CreateOnlineFeatureGroups',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:feature-group/*`],
      actions: ['sagemaker:CreateFeatureGroup'],
      conditions: {
        StringEquals: {
          'sagemaker:FeatureGroupOnlineStoreKmsKey': teamKey.keyArn,
        },
      },
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerCreateOnlineFeatureGroupStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for FeatureGroups not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:feature-group/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create offline feature-groups
    //Offline storage location must be team bucket, and must be encrypted with team key
    const sagemakerCreateOfflineFeatureGroupStatement = new PolicyStatement({
      sid: 'CreateOfflineFeatureGroups',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:feature-group/*`],
      actions: ['sagemaker:CreateFeatureGroup'],
      conditions: {
        StringEquals: {
          'sagemaker:FeatureGroupOfflineStoreKmsKey': teamKey.keyArn,
        },
        StringLike: {
          'sagemaker:FeatureGroupOfflineStoreS3Uri': teamBucket.arnForObjects('*'),
        },
      },
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerCreateOfflineFeatureGroupStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for FeatureGroups not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:feature-group/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to manage feature-groups
    const sagemakerManageFeatureGroupStatement = new PolicyStatement({
      sid: 'ManageFeatureGroups',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:feature-group/*`],
      actions: ['sagemaker:DeleteFeatureGroup', 'sagemaker:UpdateFeatureGroup', 'sagemaker:UpdateFeatureMetadata'],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerManageFeatureGroupStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for FeatureGroups not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:feature-group/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to create and manage Experiments
    const sagemakerExperimentStatement = new PolicyStatement({
      sid: 'CreateAndManageExperiments',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:experiment/*`],
      actions: ['sagemaker:CreateExperiment', 'sagemaker:DeleteExperiment', 'sagemaker:UpdateExperiment'],
    });
    sagemakerWriteManagedPolicy1.addStatements(sagemakerExperimentStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy1,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for Experiments not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:experiment/*`],
        },
      ],
      true,
    );

    //Allow SageMaker permissions required to add and remove tags (important for SageMaker Clarify, among others)
    const sagemakerAddDeleteTagsStatement = new PolicyStatement({
      sid: 'AddDeleteTagsSageMaker',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:sagemaker:${this.region}:${this.account}:*`],
      actions: ['sagemaker:AddTags', 'sagemaker:DeleteTags'],
    });
    sagemakerWriteManagedPolicy2.addStatements(sagemakerAddDeleteTagsStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy2,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for tagged SageMaker resources are not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonsagemaker.html',
          appliesTo: [`Resource::arn:${this.partition}:sagemaker:${this.region}:${this.account}:*`],
        },
      ],
      true,
    );

    //Allow EC2 permissions required to be used as execution role for VPC Bound Jobs/Pipelines
    const sagemakerEc2Statement = new PolicyStatement({
      sid: 'CreateEC2NetworkInterfaces',
      effect: Effect.ALLOW,
      resources: [`*`],
      actions: [
        'ec2:CreateNetworkInterface',
        'ec2:CreateNetworkInterfacePermission',
        'ec2:CreateVpcEndpoint',
        'ec2:DeleteNetworkInterface',
        'ec2:DeleteNetworkInterfacePermission',
        'ec2:DescribeNetworkInterfaces',
        'ec2:DescribeSecurityGroups',
        'ec2:DescribeSubnets',
        'ec2:DescribeVpcs',
        'ec2:DescribeDhcpOptions',
        'ec2:DescribeVpcEndpoints',
      ],
    });
    sagemakerWriteManagedPolicy2.addStatements(sagemakerEc2Statement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy2,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Network Interface ID not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html#amazonec2-network-interface',
          appliesTo: ['Resource::*'],
        },
      ],
      true,
    );
    //Allow SageMaker ECR permissions to pull SageMaker images from the central SageMaker repository
    const sagemakerEcrStatement = new PolicyStatement({
      sid: 'SageMakerECRReadonly',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:ecr:${this.region}:${CENTRAL_SM_REPO_ACCT}:repository/sagemaker*`],
      actions: ['ecr:ListImages', 'ecr:DescribeImages', 'ecr:DescribeRepositories', 'ecr:GetDownloadUrlForLayer'],
    });

    sagemakerWriteManagedPolicy2.addStatements(sagemakerEcrStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy2,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            'Resource names for SageMaker ECR not known at deployment time. https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonelasticcontainerregistry.html',
          appliesTo: [
            `Resource::arn:${this.partition}:ecr:${this.region}:${CENTRAL_SM_REPO_ACCT}:repository/sagemaker*`,
          ],
        },
      ],
      true,
    );

    //Allow creation of log groups and log streams for SageMaker
    const cloudwatchStatement = new PolicyStatement({
      sid: 'CloudWatchSageMaker',
      effect: Effect.ALLOW,
      resources: [`arn:${this.partition}:logs:${this.region}:${this.account}:log-group:*sagemaker*`],
      actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'],
    });
    sagemakerWriteManagedPolicy2.addStatements(cloudwatchStatement);
    MdaaNagSuppressions.addCodeResourceSuppressions(
      sagemakerWriteManagedPolicy2,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason: 'Log Group and Stream names not known at deployment time.',
          appliesTo: [`Resource::arn:${this.partition}:logs:${this.region}:${this.account}:log-group:*sagemaker*`],
        },
      ],
      true,
    );
    sagemakerWriteManagedPolicy1.checkPolicyLength(true);
    sagemakerWriteManagedPolicy2.checkPolicyLength(true);
    return [sagemakerWriteManagedPolicy1, sagemakerWriteManagedPolicy2];
  }