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];
}