# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0 resource "aws_iam_role" "gitlab_mlops_role" { assume_role_policy = jsonencode( { Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = [ "firehose.amazonaws.com", "glue.amazonaws.com", "apigateway.amazonaws.com", "lambda.amazonaws.com", "events.amazonaws.com", "states.amazonaws.com", "sagemaker.amazonaws.com", "cloudformation.amazonaws.com", "codebuild.amazonaws.com", "codepipeline.amazonaws.com" ] } }, ] Version = "2012-10-17" } ) force_detach_policies = false max_session_duration = 3600 name = "gitlab-mlops-role-${var.env}-2" path = "/service-role/" tags = {} } resource "aws_iam_policy" "gitlab_mlops_policy" { description = "Policy used in trust relationship with CodeBuild (${var.env})" name = "gitlab-mlops-policy-${var.env}-2" path = "/service-role/" policy = jsonencode( { Statement = [ { Action : [ "iam:PassRole" ], Resource : "*", Effect : "Allow" }, { "Effect" = "Allow", "Action" = [ "s3:*" ], "Resource" = [ "arn:aws:s3:::*", "arn:aws:s3:::*" ] }, { "Action" : [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect" : "Allow", "Resource" : "arn:aws:logs:*" }, { "Action": [ "codepipeline:StartPipelineExecution" ], "Resource": "arn:aws:codepipeline:*:*:*", "Effect": "Allow" }, { "Action": [ "events:DeleteRule", "events:DescribeRule", "events:PutRule", "events:PutTargets", "events:RemoveTargets" ], "Resource": [ "arn:aws:events:*:*:rule/*" ], "Effect": "Allow" }, { "Effect": "Allow", "Action": [ "sagemaker:*" ], "NotResource": [ "arn:aws:sagemaker:*:*:domain/*", "arn:aws:sagemaker:*:*:user-profile/*", "arn:aws:sagemaker:*:*:app/*", "arn:aws:sagemaker:*:*:flow-definition/*" ] }, { "Effect": "Allow", "Action": [ "sagemaker:CreatePresignedDomainUrl", "sagemaker:DescribeDomain", "sagemaker:ListDomains", "sagemaker:DescribeUserProfile", "sagemaker:ListUserProfiles", "sagemaker:*App", "sagemaker:ListApps" ], "Resource": "*" }, { "Effect": "Allow", "Action": "sagemaker:*", "Resource": [ "arn:aws:sagemaker:*:*:flow-definition/*" ], "Condition": { "StringEqualsIfExists": { "sagemaker:WorkteamType": [ "private-crowd", "vendor-crowd" ] } } }, { "Action": [ "cloudformation:CreateChangeSet", "cloudformation:CreateStack", "cloudformation:DescribeChangeSet", "cloudformation:DeleteChangeSet", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:ExecuteChangeSet", "cloudformation:SetStackPolicy", "cloudformation:UpdateStack" ], "Resource": "arn:aws:cloudformation:*:*:stack/*", "Effect": "Allow" }, { "Action": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild" ], "Resource": [ "arn:aws:codebuild:*:*:project/*", "arn:aws:codebuild:*:*:build/*" ], "Effect": "Allow" }, { "Action": [ "states:DescribeExecution", "states:GetExecutionHistory", "states:StartExecution", "states:StopExecution", "states:UpdateStateMachine" ], "Resource": [ "arn:aws:states:*:*:statemachine:*sagemaker*", "arn:aws:states:*:*:execution:*sagemaker*:*" ], "Effect": "Allow" }, { "Effect": "Allow", "Action": [ "secretsmanager:GetRandomPassword", "secretsmanager:GetResourcePolicy", "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds", "secretsmanager:ListSecrets" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:CreateBucket", "s3:GetBucketLocation", "s3:ListBucket", "s3:ListAllMyBuckets", "s3:GetBucketCors", "s3:PutBucketCors" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:GetBucketAcl", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::*SageMaker*", "arn:aws:s3:::*Sagemaker*", "arn:aws:s3:::*sagemaker*" ] }, { "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr:Describe*", "ecr:GetAuthorizationToken", "ecr:GetDownloadUrlForLayer" ], "Resource": "*", "Effect": "Allow" }, { "Effect": "Allow", "Action": [ "ecr:BatchDeleteImage", "ecr:CompleteLayerUpload", "ecr:CreateRepository", "ecr:DeleteRepository", "ecr:InitiateLayerUpload", "ecr:PutImage", "ecr:UploadLayerPart" ], "Resource": [ "arn:aws:ecr:*:*:repository/sagemaker-*" ] }, { "Action": "iam:CreateServiceLinkedRole", "Effect": "Allow", "Resource": "arn:aws:iam::*:role/aws-service-role/sagemaker.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_SageMakerEndpoint", "Condition": { "StringLike": { "iam:AWSServiceName": "sagemaker.application-autoscaling.amazonaws.com" } } }, { "Effect": "Allow", "Action": "iam:CreateServiceLinkedRole", "Resource": "*", "Condition": { "StringEquals": { "iam:AWSServiceName": "robomaker.amazonaws.com" } } }, { "Effect": "Allow", "Action": [ "sns:Subscribe", "sns:CreateTopic" ], "Resource": [ "arn:aws:sns:*:*:*SageMaker*", "arn:aws:sns:*:*:*Sagemaker*", "arn:aws:sns:*:*:*sagemaker*" ] }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "arn:aws:iam::*:role/*AmazonSageMaker*", "Condition": { "StringEquals": { "iam:PassedToService": [ "glue.amazonaws.com", "robomaker.amazonaws.com", "states.amazonaws.com" ] } } }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "arn:aws:iam::*:role/*", "Condition": { "StringEquals": { "iam:PassedToService": "sagemaker.amazonaws.com" } } } ] Version = "2012-10-17" } ) } resource "aws_iam_role_policy_attachment" "gitlab_mlops_policy_attachment" { role = aws_iam_role.gitlab_mlops_role.name policy_arn = aws_iam_policy.gitlab_mlops_policy.arn }