AWSTemplateFormatVersion: 2010-09-09 Description: >- Creates VPC and subnets for SageMaker training. Parameters: VpcCIDR: Default: 172.30.0.0/25 Description: Vpc CIDR AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' Type: String PublicSubnetCIDR: Default: 172.30.0.0/27 Description: Public Subnet CIDR in Vpc CIDR AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' Type: String PrivateSubnet1CIDR: Default: 172.30.0.32/27 Description: Private Subnet1 CIDR in Vpc CIDR AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' Type: String PrivateSubnet2CIDR: Default: 172.30.0.64/27 Description: Private Subnet2 CIDR in Vpc CIDR AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' Type: String PrivateSubnet3CIDR: Default: 172.30.0.96/27 Description: Private Subnet2 CIDR in Vpc CIDR AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' Type: String # Default: 'sagemaker-notebook' S3BucketName: Description: SageMaker S3 Bucket Name Type: String Resources: Vpc: Type: 'AWS::EC2::VPC' Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: 'true' EnableDnsHostnames: 'true' Tags: - Key: Name Value: !Ref 'AWS::StackName' InternetGateway: Type: 'AWS::EC2::InternetGateway' Properties: Tags: - Key: Network Value: Public - Key: Name Value: !Ref 'AWS::StackName' GatewayToInternet: Type: 'AWS::EC2::VPCGatewayAttachment' Properties: VpcId: !Ref Vpc InternetGatewayId: !Ref InternetGateway PublicSubnet: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref Vpc AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: "" CidrBlock: !Ref PublicSubnetCIDR Tags: - Key: Network Value: Public - Key: Name Value: !Ref 'AWS::StackName' PrivateSubnet1: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref Vpc AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: "" CidrBlock: !Ref PrivateSubnet1CIDR Tags: - Key: Network Value: Private - Key: Name Value: !Ref 'AWS::StackName' PrivateSubnet2: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref Vpc AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: "" CidrBlock: !Ref PrivateSubnet2CIDR Tags: - Key: Network Value: Private - Key: Name Value: !Ref 'AWS::StackName' PrivateSubnet3: Type: 'AWS::EC2::Subnet' Properties: VpcId: !Ref Vpc AvailabilityZone: Fn::Select: - 2 - Fn::GetAZs: "" CidrBlock: !Ref PrivateSubnet3CIDR Tags: - Key: Network Value: Private - Key: Name Value: !Ref 'AWS::StackName' NATGatewayEIP: Type: 'AWS::EC2::EIP' Properties: Domain: vpc NATGateway: Type: 'AWS::EC2::NatGateway' DependsOn: GatewayToInternet Properties: AllocationId: !GetAtt - NATGatewayEIP - AllocationId SubnetId: !Ref PublicSubnet PublicRouteTable: Type: 'AWS::EC2::RouteTable' DependsOn: GatewayToInternet Properties: VpcId: !Ref Vpc Tags: - Key: Network Value: Public - Key: Name Value: !Ref 'AWS::StackName' PublicRoute: Type: 'AWS::EC2::Route' Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnetRouteAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' DependsOn: [ PublicRoute ] Properties: SubnetId: !Ref PublicSubnet RouteTableId: !Ref PublicRouteTable PrivateRouteTable: Type: 'AWS::EC2::RouteTable' Properties: VpcId: !Ref Vpc Tags: - Key: Network Value: Private - Key: Name Value: !Ref 'AWS::StackName' PrivateRoute: Type: 'AWS::EC2::Route' DependsOn: [ NATGateway ] Properties: RouteTableId: !Ref PrivateRouteTable DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NATGateway PrivateSubnet1RouteAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' DependsOn: [ PrivateRoute ] Properties: SubnetId: !Ref PrivateSubnet1 RouteTableId: !Ref PrivateRouteTable PrivateSubnet2RouteAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' DependsOn: [ PrivateRoute ] Properties: SubnetId: !Ref PrivateSubnet2 RouteTableId: !Ref PrivateRouteTable PrivateSubnet3RouteAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' DependsOn: [ PrivateRoute ] Properties: SubnetId: !Ref PrivateSubnet3 RouteTableId: !Ref PrivateRouteTable VpcS3Endpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: "Allow" Principal: "*" Action: - "s3:*" Resource: "*" RouteTableIds: - !Ref PrivateRouteTable ServiceName: !Sub com.amazonaws.${AWS::Region}.s3 VpcId: !Ref Vpc VpcSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Security group VpcId: !Ref Vpc Tags: - Key: Name Value: !Ref 'AWS::StackName' VpcSecurityGroupIngress: Type: 'AWS::EC2::SecurityGroupIngress' Properties: GroupId: !GetAtt VpcSecurityGroup.GroupId IpProtocol: tcp FromPort: 0 ToPort: 65535 SourceSecurityGroupId: !GetAtt VpcSecurityGroup.GroupId ExecutionRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "sagemaker.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" Policies: - PolicyName: "sagemaker-policy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "ecr:GetAuthorizationToken" - "ecr:BatchCheckLayerAvailability" - "ecr:GetDownloadUrlForLayer" - "ecr:GetRepositoryPolicy" - "ecr:DescribeRepositories" - "ecr:ListImages" - "ecr:DescribeImages" - "ecr:BatchGetImage" - "ecr:InitiateLayerUpload" - "ecr:UploadLayerPart" - "ecr:CompleteLayerUpload" - "ecr:PutImage" - "ecr:CreateRepository" - "fsx:*" - "sagemaker:*" - "cloudformation:*" - "ec2:CreateNetworkInterface" - "ec2:CreateNetworkInterfacePermission" - "ec2:CreateVpcEndpoint" - "ec2:DeleteNetworkInterface" - "ec2:DeleteNetworkInterfacePermission" - "ec2:DescribeDhcpOptions" - "ec2:DescribeNetworkInterfaces" - "ec2:DescribeRouteTables" - "ec2:DescribeSecurityGroups" - "ec2:DescribeSubnets" - "ec2:DescribeVpcEndpoints" - "ec2:DescribeVpcs" - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:DescribeLogStreams" - "logs:GetLogEvents" - "logs:PutLogEvents" - "cloudwatch:DeleteAlarms" - "cloudwatch:DescribeAlarms" - "cloudwatch:GetMetricData" - "cloudwatch:GetMetricStatistics" - "cloudwatch:ListMetrics" - "cloudwatch:PutMetricAlarm" - "cloudwatch:PutMetricData" - "iam:PassRole" - "iam:ListRoles" - "kms:DescribeKey" - "kms:ListAliases" - "elasticfilesystem:DescribeMountTargets" Resource: "*" - Effect: "Allow" Action: - "iam:CreateServiceLinkedRole" - "iam:AttachRolePolicy" - "iam:PutRolePolicy" Resource: "arn:aws:iam::*:role/aws-service-role/*" - Effect: "Allow" Action: - "s3:ListBucket*" - "s3:GetBucket*" Resource: Fn::Join: - '' - - "arn:aws:s3:::" - !Ref S3BucketName - Effect: "Allow" Action: - "s3:AbortMultipartUpload" - "s3:ListMultipartUploadParts" - "s3:PutObject*" - "s3:DeleteObject*" - "s3:GetObject*" Resource: - Fn::Join: - '' - - "arn:aws:s3:::" - !Ref S3BucketName - Fn::Join: - '' - - "arn:aws:s3:::" - !Ref S3BucketName - "/*" Outputs: SageMakerExecutionRoleArn: Value: !GetAtt ExecutionRole.Arn SecurityGroup: Value: Fn::Join: - '' - - '[' - '''' - !GetAtt VpcSecurityGroup.GroupId - '''' - ']' Subnets: Value: Fn::Join: - '' - - '[' - '''' - !Ref PrivateSubnet1 - '''' - ',' - '''' - !Ref PrivateSubnet2 - '''' - ',' - '''' - !Ref PrivateSubnet3 - '''' - ']'