From 8f1da136178f5826f20de0c3f98fe6a7d92d4193 Mon Sep 17 00:00:00 2001 From: surendra alokam Date: Wed, 4 Sep 2024 10:15:54 -0500 Subject: [PATCH] deleted alb templates from aws deployments --- .../aws/parameters/ai-unlimited-with-alb.json | 114 -- .../aws/parameters/all-in-one-with-alb.json | 118 -- .../aws/parameters/jupyter-with-alb.json | 114 -- .../ai-unlimited/ai-unlimited-with-alb.yaml | 1246 --------------- .../all-in-one/all-in-one-with-alb.yaml | 1406 ----------------- .../templates/jupyter/jupyter-with-alb.yaml | 815 ---------- 6 files changed, 3813 deletions(-) delete mode 100644 deployments/aws/parameters/ai-unlimited-with-alb.json delete mode 100644 deployments/aws/parameters/all-in-one-with-alb.json delete mode 100644 deployments/aws/parameters/jupyter-with-alb.json delete mode 100644 deployments/aws/templates/ai-unlimited/ai-unlimited-with-alb.yaml delete mode 100644 deployments/aws/templates/all-in-one/all-in-one-with-alb.yaml delete mode 100644 deployments/aws/templates/jupyter/jupyter-with-alb.yaml diff --git a/deployments/aws/parameters/ai-unlimited-with-alb.json b/deployments/aws/parameters/ai-unlimited-with-alb.json deleted file mode 100644 index c705d68..0000000 --- a/deployments/aws/parameters/ai-unlimited-with-alb.json +++ /dev/null @@ -1,114 +0,0 @@ -[ - { - "ParameterKey": "AiUnlimitedName", - "ParameterValue": "test-unlimited" - }, - { - "ParameterKey": "InstanceType", - "ParameterValue": "t3.small" - }, - { - "ParameterKey": "RootVolumeSize", - "ParameterValue": "20" - }, - { - "ParameterKey": "TerminationProtection", - "ParameterValue": "false" - }, - { - "ParameterKey": "IamRole", - "ParameterValue": "New" - }, - { - "ParameterKey": "IamRoleName", - "ParameterValue": "" - }, - { - "ParameterKey": "IamPermissionsBoundary", - "ParameterValue": "" - }, - { - "ParameterKey": "AvailabilityZone", - "ParameterValue": "" - }, - { - "ParameterKey": "LoadBalancerScheme", - "ParameterValue": "internet-facing" - }, - { - "ParameterKey": "LoadBalancerSubnetOne", - "ParameterValue": "" - }, - { - "ParameterKey": "LoadBalancerSubnetTwo", - "ParameterValue": "" - }, - { - "ParameterKey": "Private", - "ParameterValue": "true" - }, - { - "ParameterKey": "Session", - "ParameterValue": "true" - }, - { - "ParameterKey": "Vpc", - "ParameterValue": "" - }, - { - "ParameterKey": "Subnet", - "ParameterValue": "" - }, - { - "ParameterKey": "KeyName", - "ParameterValue": "" - }, - { - "ParameterKey": "AccessCIDR", - "ParameterValue": "" - }, - { - "ParameterKey": "PrefixList", - "ParameterValue": "" - }, - { - "ParameterKey": "SecurityGroup", - "ParameterValue": "" - }, - { - "ParameterKey": "AiUnlimitedHttpPort", - "ParameterValue": "3000" - }, - { - "ParameterKey": "AiUnlimitedGrpcPort", - "ParameterValue": "3282" - }, - { - "ParameterKey": "AiUnlimitedVersion", - "ParameterValue": "v0.2.23" - }, - { - "ParameterKey": "UsePersistentVolume", - "ParameterValue": "New" - }, - { - "ParameterKey": "PersistentVolumeSize", - "ParameterValue": "20" - }, - { - "ParameterKey": "ExistingPersistentVolumeId", - "ParameterValue": "" - }, - { - "ParameterKey": "PersistentVolumeDeletionPolicy", - "ParameterValue": "Delete" - }, - { - "ParameterKey": "HostedZoneId", - "ParameterValue": "" - }, - { - "ParameterKey": "DnsName", - "ParameterValue": "example.domain.com" - } -] \ No newline at end of file diff --git a/deployments/aws/parameters/all-in-one-with-alb.json b/deployments/aws/parameters/all-in-one-with-alb.json deleted file mode 100644 index 89c0042..0000000 --- a/deployments/aws/parameters/all-in-one-with-alb.json +++ /dev/null @@ -1,118 +0,0 @@ - [ - { - "ParameterKey": "AiUnlimitedName", - "ParameterValue": "test-unlimited" - }, - { - "ParameterKey": "JupyterToken", - "ParameterValue": "usealongSIMPLEtokenwithoutSPECIALchars" - }, - { - "ParameterKey": "InstanceType", - "ParameterValue": "t3.small" - }, - { - "ParameterKey": "RootVolumeSize", - "ParameterValue": "20" - }, - { - "ParameterKey": "TerminationProtection", - "ParameterValue": "false" - }, - { - "ParameterKey": "IamRole", - "ParameterValue": "New" - }, - { - "ParameterKey": "IamRoleName", - "ParameterValue": "" - }, - { - "ParameterKey": "IamPermissionsBoundary", - "ParameterValue": "" - }, - { - "ParameterKey": "AvailabilityZone", - "ParameterValue": "" - }, - { - "ParameterKey": "LoadBalancerScheme", - "ParameterValue": "internet-facing" - }, - { - "ParameterKey": "LoadBalancerSubnetOne", - "ParameterValue": "" - }, - { - "ParameterKey": "LoadBalancerSubnetTwo", - "ParameterValue": "" - }, - { - "ParameterKey": "Private", - "ParameterValue": "true" - }, - { - "ParameterKey": "Session", - "ParameterValue": "true" - }, - { - "ParameterKey": "Vpc", - "ParameterValue": "" - }, - { - "ParameterKey": "Subnet", - "ParameterValue": "" - }, - { - "ParameterKey": "KeyName", - "ParameterValue": "" - }, - { - "ParameterKey": "AccessCIDR", - "ParameterValue": "" - }, - { - "ParameterKey": "PrefixList", - "ParameterValue": "" - }, - { - "ParameterKey": "SecurityGroup", - "ParameterValue": "" - }, - { - "ParameterKey": "AiUnlimitedHttpPort", - "ParameterValue": "3000" - }, - { - "ParameterKey": "AiUnlimitedGrpcPort", - "ParameterValue": "3282" - }, - { - "ParameterKey": "AiUnlimitedVersion", - "ParameterValue": "v0.2.23" - }, - { - "ParameterKey": "UsePersistentVolume", - "ParameterValue": "New" - }, - { - "ParameterKey": "PersistentVolumeSize", - "ParameterValue": "20" - }, - { - "ParameterKey": "ExistingPersistentVolumeId", - "ParameterValue": "" - }, - { - "ParameterKey": "PersistentVolumeDeletionPolicy", - "ParameterValue": "Delete" - }, - { - "ParameterKey": "HostedZoneId", - "ParameterValue": "" - }, - { - "ParameterKey": "DnsName", - "ParameterValue": "example.domain.com" - } - ] \ No newline at end of file diff --git a/deployments/aws/parameters/jupyter-with-alb.json b/deployments/aws/parameters/jupyter-with-alb.json deleted file mode 100644 index 0a5a1a1..0000000 --- a/deployments/aws/parameters/jupyter-with-alb.json +++ /dev/null @@ -1,114 +0,0 @@ -[ - { - "ParameterKey": "JupyterName", - "ParameterValue": "test-unlimited" - }, - { - "ParameterKey": "JupyterToken", - "ParameterValue": "usealongSIMPLEtokenwithoutSPECIALchars" - }, - { - "ParameterKey": "InstanceType", - "ParameterValue": "t3.small" - }, - { - "ParameterKey": "RootVolumeSize", - "ParameterValue": "20" - }, - { - "ParameterKey": "TerminationProtection", - "ParameterValue": "false" - }, - { - "ParameterKey": "IamRole", - "ParameterValue": "New" - }, - { - "ParameterKey": "IamRoleName", - "ParameterValue": "" - }, - { - "ParameterKey": "IamPermissionsBoundary", - "ParameterValue": "" - }, - { - "ParameterKey": "AvailabilityZone", - "ParameterValue": "" - }, - { - "ParameterKey": "LoadBalancerScheme", - "ParameterValue": "internet-facing" - }, - { - "ParameterKey": "LoadBalancerSubnetOne", - "ParameterValue": "" - }, - { - "ParameterKey": "LoadBalancerSubnetTwo", - "ParameterValue": "" - }, - { - "ParameterKey": "Private", - "ParameterValue": "true" - }, - { - "ParameterKey": "Session", - "ParameterValue": "true" - }, - { - "ParameterKey": "Vpc", - "ParameterValue": "" - }, - { - "ParameterKey": "Subnet", - "ParameterValue": "" - }, - { - "ParameterKey": "KeyName", - "ParameterValue": "" - }, - { - "ParameterKey": "AccessCIDR", - "ParameterValue": "" - }, - { - "ParameterKey": "PrefixList", - "ParameterValue": "" - }, - { - "ParameterKey": "SecurityGroup", - "ParameterValue": "" - }, - { - "ParameterKey": "JupyterHttpPort", - "ParameterValue": "3000" - }, - { - "ParameterKey": "JupyterVersion", - "ParameterValue": "latest" - }, - { - "ParameterKey": "UsePersistentVolume", - "ParameterValue": "New" - }, - { - "ParameterKey": "PersistentVolumeSize", - "ParameterValue": "20" - }, - { - "ParameterKey": "ExistingPersistentVolumeId", - "ParameterValue": "" - }, - { - "ParameterKey": "PersistentVolumeDeletionPolicy", - "ParameterValue": "Delete" - }, - { - "ParameterKey": "HostedZoneId", - "ParameterValue": "" - }, - { - "ParameterKey": "DnsName", - "ParameterValue": "example.domain.com" - } -] \ No newline at end of file diff --git a/deployments/aws/templates/ai-unlimited/ai-unlimited-with-alb.yaml b/deployments/aws/templates/ai-unlimited/ai-unlimited-with-alb.yaml deleted file mode 100644 index 0cac150..0000000 --- a/deployments/aws/templates/ai-unlimited/ai-unlimited-with-alb.yaml +++ /dev/null @@ -1,1246 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" - -Description: 'AWS CloudFormation Template AI Unlimited: AI Unlimited is a instance based service for deploying and suspending clusters of AI Unlimited compute engines, and managing project lifecycles. Note: You will be billed for the AWS resources used if you create a stack from this template.' - -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: AI Unlimited - Parameters: - - AiUnlimitedName - - InstanceType - - RootVolumeSize - - TerminationProtection - - IamRole - - IamRoleName - - IamPermissionsBoundary - - Label: - default: AI Unlimited connection - Parameters: - - AvailabilityZone - - LoadBalancerScheme - - LoadBalancerSubnetOne - - LoadBalancerSubnetTwo - - HostedZoneId - - DnsName - - Private - - Session - - Vpc - - Subnet - - KeyName - - AccessCIDR - - PrefixList - - SecurityGroup - - AiUnlimitedHttpPort - - AiUnlimitedGrpcPort - - AiUnlimitedVersion - - AiUnlimitedSchedulerVersion - - AiUnlimitedSchedulerHttpPort - - AiUnlimitedSchedulerGrpcPort - - Label: - default: Persistent volume - Parameters: - - UsePersistentVolume - - PersistentVolumeSize - - ExistingPersistentVolumeId - - PersistentVolumeDeletionPolicy - -Parameters: - LatestAmiId: - Type: AWS::SSM::Parameter::Value - Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 - - AiUnlimitedName: - Description: The AI Unlimited instance name - Type: String - Default: ai-unlimited - AllowedPattern: ^[a-zA-Z][a-zA-Z0-9-]* - ConstraintDescription: must begin with a letter and contain only alphanumeric characters. - MaxLength: "20" - MinLength: "1" - - Private: - Description: Will AI Unlimited be deployed in a private network without public IPs? - Type: String - AllowedValues: - - true - - false - Default: false - - LoadBalancerScheme: - Description: "If using a LoadBalancer, will it be internal or internet-facing? \nThe DNS name of an Internet-facing load balancer is publicly resolvable to the public IP addresses of the nodes.\nTherefore, Internet-facing load balancers can route requests from clients over the internet. The nodes of an \ninternal load balancer have only private IP addresses. The DNS name of an internal load balancer is publicly\nresolvable to the private IP addresses of the nodes. Therefore, internal load balancers can route requests only\nfrom clients with access to the VPC for the load balancer.\n" - Type: String - AllowedValues: - - internal - - internet-facing - Default: internet-facing - - Session: - Description: Should AI Unlimited be accessible via AWS Session Manager? - Type: String - AllowedValues: - - true - - false - Default: false - - Vpc: - Description: Network to deploy the AI Unlimited to. - Type: AWS::EC2::VPC::Id - ConstraintDescription: must be the name of an existing vpc. - - Subnet: - Description: Subnetwork to deploy the AI Unlimited to. - Type: AWS::EC2::Subnet::Id - ConstraintDescription: must be the name of a existing subnet. - - AvailabilityZone: - Description: "Availability zone to deploy the AI Unlimited to.\nThis must match the subnet, the zone of any pre existing volumes if used, \nand the instance type must be available in the selected zone.\n" - Type: AWS::EC2::AvailabilityZone::Name - ConstraintDescription: must be the name of a existing subnet. - - LoadBalancerSubnetOne: - Description: First subnetwork to deploy the Application Load Balancer to. - Type: AWS::EC2::Subnet::Id - - LoadBalancerSubnetTwo: - Description: Second subnetwork to deploy the Application Load Balancer to. - Type: AWS::EC2::Subnet::Id - - HostedZoneId: - Description: Zone ID of an existing Route 53 zone to add an entry for the Application Load Balancer to. - Type: AWS::Route53::HostedZone::Id - - DnsName: - Description: | - Name for Load Balancer DNS Entry, must fit as subdomain in the provides Route 53 Hosted Zone ID. - Example: unlimited.yourhostedzonedomainname.com - Type: String - - AiUnlimitedHttpPort: - Description: port to access the AI Unlimited UI. - Type: Number - Default: 3000 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedSchedulerHttpPort: - Description: port to access the AI Unlimited Scheduler API. - Type: Number - Default: 50061 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedSchedulerGrpcPort: - Description: port to access the AI Unlimited Scheduler API. - Type: Number - Default: 50051 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedGrpcPort: - Description: port to access the AI Unlimited API. - Type: Number - Default: 3282 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedVersion: - Description: Which version of AI Unlimited to deploy, uses container version tags, defaults to "latest" - Type: String - Default: v0.2.23 - - AiUnlimitedSchedulerVersion: - Description: Which version of AI Unlimited Scheduler to deploy, uses container version tags, defaults to "latest" - Type: String - Default: latest - - RootVolumeSize: - Description: size of the root disk to the AI Unlimited server. - Type: Number - Default: 20 - ConstraintDescription: Size in GB, between 10 and 1000. - MinValue: 8 - MaxValue: 1000 - - UsePersistentVolume: - Description: Should we use a new or existing volume for persistent data on the AI Unlimited server. - Type: String - AllowedValues: - - New - - Existing - Default: New - ConstraintDescription: Specify if you are using a a new persistent volume, an existing one, or none. - - PersistentVolumeSize: - Description: size of the optional persistent disk to the AI Unlimited server. - Type: Number - Default: 20 - ConstraintDescription: Size in GB, between 10 and 1000. - MinValue: 8 - MaxValue: 1000 - - ExistingPersistentVolumeId: - Description: Id of the existing persistent volume to attach. Must be int the same availability zone as the AI Unlimited server. - Type: String - Default: None - - PersistentVolumeDeletionPolicy: - Description: Behavior for the Persistent Volume when deleting the cloudformations deployment. - Type: String - AllowedValues: - - Delete - - Retain - - RetainExceptOnCreate - - Snapshot - Default: Retain - - TerminationProtection: - Description: Enable instance termination protection. - Type: String - AllowedValues: - - true - - false - Default: false - - InstanceType: - Description: AI Unlimited EC2 instance type - Type: String - AllowedValues: - - t3.nano - - t3.micro - - t3.small - - t3.medium - - t3.large - - m3.medium - - m3.large - - m3.xlarge - - m3.2xlarge - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - - c3.large - - c3.xlarge - - c3.2xlarge - - c3.4xlarge - - c3.8xlarge - - c4.large - - c4.xlarge - - c4.2xlarge - - c4.4xlarge - - c4.8xlarge - - r3.large - - r3.xlarge - - r3.2xlarge - - r3.4xlarge - - r3.8xlarge - - i2.xlarge - - i2.2xlarge - - i2.4xlarge - - i2.8xlarge - Default: t3.micro - ConstraintDescription: must be a valid EC2 instance type. - - KeyName: - Description: Name of an existing EC2 KeyPair to enable SSH access to the AI Unlimited instance, leave empty if no ssh keys should be included - Type: String - - IamRole: - Description: | - Create a new IAM role for AI Unlimited or use an exiting one. - Requires CAPABILITY_IAM if creating a new IAM Role - Type: String - AllowedValues: - - New - - Existing - Default: New - - IamRoleName: - Description: | - Name of an existing IAM Role to assign to AI Unlimited, - or the name to give to the newly created role. - Leave blank to use an autogenerated name. - Requires CAPABILITY_NAMED_IAM if naming a new IAM Role. - Type: String - - IamPermissionsBoundary: - Description: | - Optional: Arn of a permissions boundary to pass to the IAM Role assigned to AI Unlimited. - Type: String - - AccessCIDR: - Description: The IP address range that can be used to communicate with the AI Unlimited instance. - Type: String - AllowedPattern: ((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2}))|^$ - ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. - - PrefixList: - Description: The PrefixList that can be used to communicate with the AI Unlimited instance. - Type: String - ConstraintDescription: must be a valid prefixlist - - SecurityGroup: - Description: The SecurityGroup that can be used to communicate with the AI Unlimited instance. - Type: String - ConstraintDescription: must be a valid securityGroup ID - -Rules: - subnetsInVpc: - Assertions: - - Assert: - Fn::EachMemberEquals: - - Fn::ValueOfAll: - - AWS::EC2::Subnet::Id - - VpcId - - !Ref Vpc - AssertDescription: The subnet you selected is not in the VPC - - instanceTypeInZone: - Assertions: - - Assert: - Fn::EachMemberEquals: - - Fn::ValueOfAll: - - AWS::EC2::Subnet::Id - - VpcId - - !Ref Vpc - AssertDescription: The subnet you selected is not in the VPC - -Conditions: - NEEDSROLE: !Equals - - !Ref IamRole - - New - - HASPUBLICIP: !Not - - !Equals - - !Ref Private - - "true" - - HASKEY: !Not - - !Equals - - !Ref KeyName - - "" - - HASCIDR: !Not - - !Equals - - !Ref AccessCIDR - - "" - - HASPREFIXLIST: !Not - - !Equals - - !Ref PrefixList - - "" - - HASSECURITYGROUP: !Not - - !Equals - - !Ref SecurityGroup - - "" - - HASCIDRORPREFIXLIST: !Or - - !Condition HASCIDR - - !Condition HASPREFIXLIST - - HASCIDRORPREFIXLISTORSECGROUP: !Or - - !Condition HASCIDR - - !Condition HASPREFIXLIST - - !Condition HASSECURITYGROUP - - USESESSIONMANAGER: !Equals - - !Ref Session - - "true" - - NEEDSROLEANDSESSIONMANAGER: !And - - !Condition NEEDSROLE - - !Condition USESESSIONMANAGER - - HASKEYANDPUBLIC: !And - - !Condition HASKEY - - !Condition HASPUBLICIP - - HASKEYANDCIDRORPREFIXLISTORSECGROUP: !And - - !Condition HASKEY - - !Condition HASCIDRORPREFIXLISTORSECGROUP - - USENEWPERSISTENTVOLUME: !Equals - - !Ref UsePersistentVolume - - New - - HASIAMPERMISSIONSBOUNDARY: !Not - - !Equals - - !Ref IamPermissionsBoundary - - "" - - HASIAMROLENAME: !Not - - !Equals - - !Ref IamRoleName - - "" - -Resources: - AiUnlimitedVolume: - DeletionPolicy: !Ref PersistentVolumeDeletionPolicy - Type: AWS::EC2::Volume - Properties: - AvailabilityZone: !Ref AvailabilityZone - Size: !Ref PersistentVolumeSize - Encrypted: true - Tags: - - Key: Name - Value: !Join - - '-' - - - !Ref AiUnlimitedName - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - Key: Usage - Value: persistent storage - Condition: USENEWPERSISTENTVOLUME - - AiUnlimitedServer: - CreationPolicy: - ResourceSignal: - Timeout: PT15M - Type: AWS::EC2::Instance - Metadata: - AWS::CloudFormation::Init: - configSets: - ai_unlimited_install: - - prepare_directory - - !If - - USENEWPERSISTENTVOLUME - - prepare_new_storage - - !Ref AWS::NoValue - - bind_storage - - mount_storage - - install_docker - - configure_ai_unlimited_service - - start_ai_unlimited_service - - configure_ai_unlimited_scheduler_service - - start_ai_unlimited_scheduler_service - prepare_directory: - commands: - mkdir: - command: !Sub | - #!/bin/bash -xe - mkdir -p /etc/td - prepare_new_storage: - commands: - mkfs: - command: !Sub | - #!/bin/bash -xe - /usr/sbin/mkfs -t ext4 /dev/nvme1n1 - bind_storage: - commands: - fstab: - command: !Sub | - #!/bin/bash -xe - /usr/bin/echo "/dev/nvme1n1 /etc/td ext4 defaults 0 2" >> /etc/fstab - mount_storage: - commands: - mount: - command: !Sub | - #!/bin/bash -xe - /usr/bin/mount -a - install_docker: - files: - /usr/lib/systemd/system/docker-install.service: - content: !Sub | - [Unit] - Description=Install docker - - [Service] - Type=oneshot - ExecStart=/bin/bash -c "while ! dnf update; do sleep 2; done && while ! dnf install -y docker; do sleep 2; done" - RemainAfterExit=yes - - [Install] - WantedBy=multi-user.target - commands: - verify_docker: - command: !Sub | - #!/bin/bash -xe - systemctl start docker-install - systemctl start docker - systemctl enable docker - services: - systemd: - docker: - enabled: "true" - ensureRunning: "true" - configure_ai_unlimited_service: - files: - /usr/lib/systemd/system/ai-unlimited.service: - content: !Sub | - [Unit] - Description=AI Unlimited - After=docker.service - Requires=docker.service - StartLimitInterval=200 - StartLimitBurst=10 - - [Service] - TimeoutStartSec=0 - Restart=always - RestartSec=2 - ExecStartPre=-/usr/bin/mkdir -p /etc/td/ai-unlimited - ExecStartPre=-/usr/bin/docker exec %n stop || true - ExecStartPre=-/usr/bin/docker rm %n || true - ExecStartPre=-/bin/bash -c '/usr/bin/docker network create -d bridge ai_unlimited || true' - ExecStartPre=/usr/bin/docker pull teradata/ai-unlimited-workspaces:${ AiUnlimitedVersion } - ExecStart=/usr/bin/docker run \ - -e accept_license=Y \ - -e PLATFORM=aws \ - -v /etc/td/ai-unlimited:/etc/td \ - -p ${ AiUnlimitedHttpPort }:3000 \ - -p ${ AiUnlimitedGrpcPort }:3282 \ - --rm --name %n teradata/ai-unlimited-workspaces:${ AiUnlimitedVersion } workspaces serve -v - - [Install] - WantedBy=multi-user.target - group: root - mode: "000400" - owner: root - start_ai_unlimited_service: - services: - systemd: - ai-unlimited: - enabled: "true" - ensureRunning: "true" - configure_ai_unlimited_scheduler_service: - files: - /usr/lib/systemd/system/ai-unlimited-scheduler.service: - content: !Sub | - [Unit] - Description=AI Unlimited Scheduler - After=docker.service - Requires=docker.service - StartLimitInterval=200 - StartLimitBurst=10 - - [Service] - TimeoutStartSec=0 - Restart=always - RestartSec=2 - ExecStartPre=-/usr/bin/docker exec %n stop || true - ExecStartPre=-/usr/bin/docker rm %n || true - ExecStartPre=/usr/bin/docker pull teradata/ai-unlimited-scheduler:latest - ExecStart=/usr/bin/docker run \ - --network ai_unlimited \ - -p ${ AiUnlimitedSchedulerGrpcPort }:50051 \ - -p ${ AiUnlimitedSchedulerHttpPort }:50061 \ - -v /etc/td/ai-unlimited:/etc/td \ - -e TD_WSSCHED_LOG_PATH=/etc/td/workspaces/scheduler_logs \ - -e TD_WSSCHED_TASK_LOG_PATH=/etc/td/workspaces/scheduler_logs/projects \ - -e TD_WSSCHED_POL_INTERVAL=60 \ - -e TD_WS_CONTAINER_NAME=ai-unlimited.service \ - --rm --name %n teradata/ai-unlimited-scheduler:latest workspace-event-scheduler serve - [Install] - WantedBy=multi-user.target - group: root - mode: "000400" - owner: root - start_ai_unlimited_scheduler_service: - services: - systemd: - ai-unlimited-scheduler: - enabled: "true" - ensureRunning: "true" - Properties: - PropagateTagsToVolumeOnCreation: true - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - VolumeSize: !Ref RootVolumeSize - Encrypted: true - NetworkInterfaces: - - DeviceIndex: 0 - SubnetId: !Ref Subnet - GroupSet: - - !GetAtt AiUnlimitedSecurityGroup.GroupId - - !GetAtt AiUnlimitedSchedulerSecurityGroup.GroupId - AssociatePublicIpAddress: !If - - HASPUBLICIP - - true - - !Ref AWS::NoValue - ImageId: !Ref LatestAmiId - InstanceType: !Ref InstanceType - KeyName: !If - - HASKEY - - !Ref KeyName - - !Ref AWS::NoValue - DisableApiTermination: !Ref TerminationProtection - IamInstanceProfile: !Ref AiUnlimitedInstanceProfile - Volumes: - - Device: /dev/xvdb - VolumeId: !If - - USENEWPERSISTENTVOLUME - - !Ref AiUnlimitedVolume - - !Ref ExistingPersistentVolumeId - Tags: - - Key: Name - Value: !Join - - '-' - - - !Ref AiUnlimitedName - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - UserData: !Base64 - Fn::Sub: | - #!/bin/bash -xe - yum update -y - yum update -y aws-cfn-bootstrap - /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource AiUnlimitedServer --configsets ai_unlimited_install --region ${AWS::Region} - /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource AiUnlimitedServer --region ${AWS::Region} - - LoadBalancerAiUnlimitedSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server from LoadBalancer over http, grpc, and ssh - SecurityGroupIngress: - - FromPort: !Ref AiUnlimitedHttpPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedHttpPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - - FromPort: !Ref AiUnlimitedGrpcPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedGrpcPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASCIDRORPREFIXLISTORSECGROUP - - LoadBalancerSchedulerSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server from LoadBalancer over http, grpc, and ssh - SecurityGroupIngress: - - FromPort: !Ref AiUnlimitedSchedulerHttpPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedSchedulerHttpPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - - FromPort: !Ref AiUnlimitedSchedulerGrpcPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedSchedulerGrpcPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASCIDRORPREFIXLISTORSECGROUP - - LoadBalancer: - Type: AWS::ElasticLoadBalancingV2::LoadBalancer - Properties: - Scheme: !Ref LoadBalancerScheme - Subnets: - - !Ref LoadBalancerSubnetOne - - !Ref LoadBalancerSubnetTwo - SecurityGroups: - - !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - Type: application - - AiUnlimitedHTTPListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref AiUnlimitedHTTPTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref AiUnlimitedHttpPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - AiUnlimitedGRPCListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref AiUnlimitedGRPCTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref AiUnlimitedGrpcPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - AiUnlimitedSchedulerHTTPListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref AiUnlimitedSchedulerHTTPTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref AiUnlimitedSchedulerHttpPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - AiUnlimitedSchedulerGRPCListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref AiUnlimitedSchedulerGRPCTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref AiUnlimitedSchedulerGrpcPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - AiUnlimitedHTTPTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTP - HealthCheckTimeoutSeconds: 15 - Matcher: - HttpCode: "200" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - td-aiu - - ui - - http - Port: !Ref AiUnlimitedHttpPort - Protocol: HTTP - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDWUNLIMITEDHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedHttpPort - VpcId: !Ref Vpc - - AiUnlimitedGRPCTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTPS - HealthCheckTimeoutSeconds: 15 - HealthyThresholdCount: 5 - Matcher: - GrpcCode: "0" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - td-aiu - - api - - grpc - Port: !Ref AiUnlimitedGrpcPort - Protocol: HTTP - ProtocolVersion: GRPC - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDUNLIMITEDSGRPCSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedGrpcPort - VpcId: !Ref Vpc - - AiUnlimitedSchedulerHTTPTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTP - HealthCheckTimeoutSeconds: 15 - HealthCheckPath: /healthcheck - Matcher: - HttpCode: "200" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - aisch - - ui - - http - Port: !Ref AiUnlimitedSchedulerHttpPort - Protocol: HTTPS - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDWUNLIMITEDHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedSchedulerHttpPort - VpcId: !Ref Vpc - - AiUnlimitedSchedulerGRPCTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTPS - HealthCheckTimeoutSeconds: 15 - Matcher: - GrpcCode: "0" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - aisch - - api - - grpc - Port: !Ref AiUnlimitedSchedulerGrpcPort - Protocol: HTTPS - ProtocolVersion: GRPC - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDWUNLIMITEDHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedSchedulerGrpcPort - VpcId: !Ref Vpc - - AiUnlimitedSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server over http and grpc - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedHttpPort - ToPort: !Ref AiUnlimitedHttpPort - SourceSecurityGroupId: !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedGrpcPort - ToPort: !Ref AiUnlimitedGrpcPort - SourceSecurityGroupId: !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedHttpPort - ToPort: !Ref AiUnlimitedHttpPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedGrpcPort - ToPort: !Ref AiUnlimitedGrpcPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - AiUnlimitedSchedulerSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server over http and grpc - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerGrpcPort - ToPort: !Ref AiUnlimitedSchedulerGrpcPort - SourceSecurityGroupId: !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerHttpPort - ToPort: !Ref AiUnlimitedSchedulerHttpPort - SourceSecurityGroupId: !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerHttpPort - ToPort: !Ref AiUnlimitedSchedulerHttpPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerGrpcPort - ToPort: !Ref AiUnlimitedSchedulerGrpcPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - SecurityGroupIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !GetAtt AiUnlimitedSecurityGroup.GroupId - FromPort: 22 - IpProtocol: tcp - ToPort: 22 - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASKEYANDCIDRORPREFIXLISTORSECGROUP - - AiUnlimitedRole: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com - Action: - - sts:AssumeRole - Path: / - RoleName: !If - - HASIAMROLENAME - - !Ref IamRoleName - - !Ref AWS::NoValue - PermissionsBoundary: !If - - HASIAMPERMISSIONSBOUNDARY - - !Ref IamPermissionsBoundary - - !Ref AWS::NoValue - Condition: NEEDSROLE - - SessionManagerPolicies: - Type: AWS::IAM::Policy - Properties: - PolicyName: !Join - - '-' - - - ai-unlimited - - session - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Action: - - ssm:DescribeAssociation - - ssm:GetDeployablePatchSnapshotForInstance - - ssm:GetDocument - - ssm:DescribeDocument - - ssm:GetManifest - - ssm:ListAssociations - - ssm:ListInstanceAssociations - - ssm:PutInventory - - ssm:PutComplianceItems - - ssm:PutConfigurePackageResult - - ssm:UpdateAssociationStatus - - ssm:UpdateInstanceAssociationStatus - - ssm:UpdateInstanceInformation - Resource: '*' - - Effect: Allow - Action: - - ssmmessages:CreateControlChannel - - ssmmessages:CreateDataChannel - - ssmmessages:OpenControlChannel - - ssmmessages:OpenDataChannel - Resource: '*' - - Effect: Allow - Action: - - ec2messages:AcknowledgeMessage - - ec2messages:DeleteMessage - - ec2messages:FailMessage - - ec2messages:GetEndpoint - - ec2messages:GetMessages - - ec2messages:SendReply - Resource: '*' - Roles: - - !Ref AiUnlimitedRole - Condition: NEEDSROLEANDSESSIONMANAGER - - AiUnlimitedRolePolicies: - Type: AWS::IAM::Policy - Properties: - PolicyName: !Join - - '-' - - - ai-unlimited - - deploy - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Action: - - iam:PassRole - - iam:AddRoleToInstanceProfile - - iam:CreateInstanceProfile - - iam:CreateRole - - iam:DeleteInstanceProfile - - iam:DeleteRole - - iam:DeleteRolePolicy - - iam:GetInstanceProfile - - iam:GetRole - - iam:GetRolePolicy - - iam:ListAttachedRolePolicies - - iam:ListInstanceProfilesForRole - - iam:ListRolePolicies - - iam:PutRolePolicy - - iam:RemoveRoleFromInstanceProfile - - iam:TagRole - - iam:TagInstanceProfile - - ec2:TerminateInstances - - ec2:RunInstances - - ec2:RevokeSecurityGroupEgress - - ec2:ModifyInstanceAttribute - - ec2:ImportKeyPair - - ec2:DescribeVpcs - - ec2:DescribeVolumes - - ec2:DescribeTags - - ec2:DescribeSubnets - - ec2:DescribeSecurityGroups - - ec2:DescribePlacementGroups - - ec2:DescribeNetworkInterfaces - - ec2:DescribeLaunchTemplates - - ec2:DescribeLaunchTemplateVersions - - ec2:DescribeKeyPairs - - ec2:DescribeInstanceTypes - - ec2:DescribeInstanceTypeOfferings - - ec2:DescribeInstances - - ec2:DescribeInstanceAttribute - - ec2:DescribeImages - - ec2:DescribeAccountAttributes - - ec2:DescribeAvailabilityZones - - ec2:DescribeManagedPrefixLists - - ec2:DescribeVpcAttribute - - ec2:DeleteSecurityGroup - - ec2:DeletePlacementGroup - - ec2:DeleteLaunchTemplate - - ec2:DeleteKeyPair - - ec2:CreateTags - - ec2:CreateSecurityGroup - - ec2:CreatePlacementGroup - - ec2:CreateLaunchTemplateVersion - - ec2:CreateLaunchTemplate - - ec2:AuthorizeSecurityGroupIngress - - ec2:AuthorizeSecurityGroupEgress - - secretsmanager:CreateSecret - - secretsmanager:DeleteSecret - - secretsmanager:DescribeSecret - - secretsmanager:GetResourcePolicy - - secretsmanager:GetSecretValue - - secretsmanager:PutSecretValue - - secretsmanager:TagResource - - s3:CreateBucket - - s3:DeleteBucket - - s3:PutObject - - s3:GetObject - - cloudformation:CreateStack - - cloudformation:DeleteStack - - cloudformation:DescribeStacks - - cloudformation:ListStacks - - cloudformation:DescribeStackEvents - - ssm:PutParameter - - ssm:GetParameter - - ssm:DeleteParameter - - ec2:RevokeSecurityGroupIngress - - ec2:CreateInternetGateway - - ec2:CreateVpc - - ec2:DescribeInternetGateways - - ec2:DeleteVpc - - ec2:ModifyVpcAttribute - - ec2:DeleteInternetGateway - - ec2:CreateSubnet - - ec2:CreateRouteTable - - ec2:DescribeRouteTables - - ec2:DeleteSubnet - - ec2:DeleteRouteTable - - ec2:AttachInternetGateway - - ec2:ModifySubnetAttribute - - ec2:DetachInternetGateway - - ec2:AssociateRouteTable - - ec2:CreateRoute - - ec2:DisassociateRouteTable - - ec2:DeleteRoute - Resource: '*' - Roles: - - !Ref AiUnlimitedRole - Condition: NEEDSROLE - - AiUnlimitedInstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - Path: / - Roles: !If - - NEEDSROLE - - - !Ref AiUnlimitedRole - - - !Ref IamRoleName - - ACMCertificate: - Type: AWS::CertificateManager::Certificate - Properties: - DomainName: !Ref DnsName - DomainValidationOptions: - - DomainName: !Ref DnsName - HostedZoneId: !Ref HostedZoneId - ValidationMethod: DNS - - LoadBalancerDNS: - Type: AWS::Route53::RecordSetGroup - Properties: - HostedZoneId: !Ref HostedZoneId - RecordSets: - - Name: !Ref DnsName - Type: A - AliasTarget: - HostedZoneId: !GetAtt LoadBalancer.CanonicalHostedZoneID - DNSName: !GetAtt LoadBalancer.DNSName - -Outputs: - PublicIP: - Description: EC2 public IP - Value: !GetAtt AiUnlimitedServer.PublicIp - Condition: HASPUBLICIP - - PrivateIP: - Description: EC2 private IP - Value: !GetAtt AiUnlimitedServer.PrivateIp - - AiUnlimitedUiAccess: - Description: Loadbalancer access endpoint for AI Unlimited UI Access - Value: !Sub https://${ DnsName }:${ AiUnlimitedHttpPort } - - AiUnlimitedApiAccess: - Description: Loadbalancer access endpoint for AI Unlimited API Access - Value: !Sub ${ DnsName }:${ AiUnlimitedGrpcPort } - - InstanceSecurityGroups: - Description: AI Unlimited Security Group - Value: !Join - - ', ' - - - !GetAtt AiUnlimitedSecurityGroup.GroupId - - !GetAtt AiUnlimitedSchedulerSecurityGroup.GroupId - - LoadBalancerSecurityGroups: - Description: AI Unlimited Load Balancer Security Group - Value: !Join - - ', ' - - - !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - - PublicSshConeection: - Description: AI Unlimited ssh connnection string - Value: !Sub ssh ec2-user@${ AiUnlimitedServer.PublicIp } - Condition: HASKEYANDPUBLIC - - PrivateSshConeection: - Description: AI Unlimited ssh connnection string - Value: !Sub ssh ec2-user@${ AiUnlimitedServer.PrivateIp } - Condition: HASKEY - - PersistentVolumeId: - Description: Id of the new persistent volume created for AI Unlimited - Value: !Ref AiUnlimitedVolume - Condition: USENEWPERSISTENTVOLUME \ No newline at end of file diff --git a/deployments/aws/templates/all-in-one/all-in-one-with-alb.yaml b/deployments/aws/templates/all-in-one/all-in-one-with-alb.yaml deleted file mode 100644 index 86dab85..0000000 --- a/deployments/aws/templates/all-in-one/all-in-one-with-alb.yaml +++ /dev/null @@ -1,1406 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" - -Description: 'AWS CloudFormation Template with AI Unlimited with Jupyter: AI Unlimited is a instance based service for deploying and suspending ai-unlimited clusters, and managing project lifecycles. This template also includes a Jupyter Lab service running on the same host, suitable for demonstration environments. Note: You will be billed for the AWS resources used if you create a stack from this template.' - -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: AI Unlimited - Parameters: - - AiUnlimitedName - - InstanceType - - RootVolumeSize - - TerminationProtection - - IamRole - - IamRoleName - - IamPermissionsBoundary - - Label: - default: AI Unlimited connection - Parameters: - - AvailabilityZone - - LoadBalancerScheme - - LoadBalancerSubnetOne - - LoadBalancerSubnetTwo - - HostedZoneId - - DnsName - - Private - - Session - - Vpc - - Subnet - - KeyName - - AccessCIDR - - PrefixList - - SecurityGroup - - AiUnlimitedHttpPort - - AiUnlimitedGrpcPort - - AiUnlimitedVersion - - AiUnlimitedSchedulerVersion - - AiUnlimitedSchedulerHttpPort - - AiUnlimitedSchedulerGrpcPort - - Label: - default: Persistent volume - Parameters: - - UsePersistentVolume - - PersistentVolumeSize - - ExistingPersistentVolumeId - - PersistentVolumeDeletionPolicy - - Label: - default: Jupyter connection - Parameters: - - JupyterToken - - JupyterHttpPort - - JupyterVersion - -Parameters: - LatestAmiId: - Type: AWS::SSM::Parameter::Value - Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 - - AiUnlimitedName: - Description: The AI Unlimited instance name - Type: String - Default: ai-unlimited - AllowedPattern: ^[a-zA-Z][a-zA-Z0-9-]* - ConstraintDescription: must begin with a letter and contain only alphanumeric characters. - MaxLength: "20" - MinLength: "1" - - JupyterToken: - Description: The token or password equivalent used to access Jupyter. - Type: String - NoEcho: true - AllowedPattern: ^[a-zA-Z][a-zA-Z0-9-]* - ConstraintDescription: must begin with a letter and contain only alphanumeric characters. - MaxLength: "64" - - Private: - Description: Will AI Unlimited be deployed in a private network without public IPs? - Type: String - AllowedValues: - - true - - false - Default: false - - LoadBalancerScheme: - Description: "If using a LoadBalancer, will it be internal or internet-facing? \nThe DNS name of an Internet-facing load balancer is publicly resolvable to the public IP addresses of the nodes.\nTherefore, Internet-facing load balancers can route requests from clients over the internet. The nodes of an \ninternal load balancer have only private IP addresses. The DNS name of an internal load balancer is publicly\nresolvable to the private IP addresses of the nodes. Therefore, internal load balancers can route requests only\nfrom clients with access to the VPC for the load balancer.\n" - Type: String - AllowedValues: - - internal - - internet-facing - Default: internet-facing - - Session: - Description: Should AI Unlimited be accessible via AWS Session Manager? - Type: String - AllowedValues: - - true - - false - Default: false - - Vpc: - Description: Network to deploy the AI Unlimited to. - Type: AWS::EC2::VPC::Id - ConstraintDescription: must be the name of an existing vpc. - - Subnet: - Description: Subnetwork to deploy the AI Unlimited to. - Type: AWS::EC2::Subnet::Id - ConstraintDescription: must be the name of a existing subnet. - - AvailabilityZone: - Description: "Availability zone to deploy the AI Unlimited to.\nThis must match the subnet, the zone of any pre existing volumes if used, \nand the instance type must be available in the selected zone.\n" - Type: AWS::EC2::AvailabilityZone::Name - ConstraintDescription: must be the name of a existing subnet. - - LoadBalancerSubnetOne: - Description: First subnetwork to deploy the Application Load Balancer to. - Type: AWS::EC2::Subnet::Id - - LoadBalancerSubnetTwo: - Description: Second subnetwork to deploy the Application Load Balancer to. - Type: AWS::EC2::Subnet::Id - - HostedZoneId: - Description: Zone ID of an existing Route 53 zone to add an entry for the Application Load Balancer to. - Type: AWS::Route53::HostedZone::Id - - DnsName: - Description: | - Name for Load Balancer DNS Entry, must fit as subdomain in the provides Route 53 Hosted Zone ID. - Example: unlimited.yourhostedzonedomainname.com - Type: String - - AiUnlimitedHttpPort: - Description: port to access the AI Unlimited UI. - Type: Number - Default: 3000 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedGrpcPort: - Description: port to access the AI Unlimited API. - Type: Number - Default: 3282 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedSchedulerHttpPort: - Description: port to access the AI Unlimited Scheduler API. - Type: Number - Default: 50061 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedSchedulerGrpcPort: - Description: port to access the AI Unlimited Scheduler API. - Type: Number - Default: 50051 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - AiUnlimitedVersion: - Description: Which version of AI Unlimited to deploy, uses container version tags, defaults to "latest" - Type: String - Default: v0.2.23 - - AiUnlimitedSchedulerVersion: - Description: Which version of AI Unlimited Scheduler to deploy, uses container version tags, defaults to "latest" - Type: String - Default: latest - - JupyterHttpPort: - Description: port to access the Jupyter UI. - Type: Number - Default: 8888 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - JupyterVersion: - Description: Which version of Jupyter to deploy, uses container version tags, defaults to "latest" - Type: String - Default: latest - - RootVolumeSize: - Description: size of the root disk to the AI Unlimited server. - Type: Number - Default: 20 - ConstraintDescription: Size in GB, between 10 and 1000. - MinValue: 8 - MaxValue: 1000 - - UsePersistentVolume: - Description: Should we use a new or existing volume for persistent data on the AI Unlimited server. - Type: String - AllowedValues: - - New - - Existing - Default: New - ConstraintDescription: Specify if you are using a a new persistent volume, an existing one, or none. - - PersistentVolumeSize: - Description: size of the optional persistent disk to the AI Unlimited server. - Type: Number - Default: 20 - ConstraintDescription: Size in GB, between 10 and 1000. - MinValue: 8 - MaxValue: 1000 - - ExistingPersistentVolumeId: - Description: Id of the existing persistent volume to attach. Must be in the same availability zone as the AI Unlimited instance. - Type: String - Default: None - - PersistentVolumeDeletionPolicy: - Description: Behavior for the Persistent Volume when deleting the cloudformations deployment. - Type: String - AllowedValues: - - Delete - - Retain - - RetainExceptOnCreate - - Snapshot - Default: Retain - - TerminationProtection: - Description: Enable instance termination protection. - Type: String - AllowedValues: - - true - - false - Default: false - - InstanceType: - Description: AI Unlimited EC2 instance type - Type: String - AllowedValues: - - t3.small - - t3.medium - - t3.large - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - - c4.large - - c4.xlarge - - c4.2xlarge - - c4.4xlarge - - c4.8xlarge - - r3.large - - r3.xlarge - - r3.2xlarge - - r3.4xlarge - - r3.8xlarge - - i2.xlarge - - i2.2xlarge - - i2.4xlarge - - i2.8xlarge - Default: t3.small - ConstraintDescription: must be a valid EC2 instance type. - - KeyName: - Description: Name of an existing EC2 KeyPair to enable SSH access to the AI Unlimited instance, leave empty if no ssh keys should be included - Type: String - - IamRole: - Description: | - Create a new IAM role for AI Unlimited or use an exiting one. - Requires CAPABILITY_IAM if creating a new IAM Role - Type: String - AllowedValues: - - New - - Existing - Default: New - - IamRoleName: - Description: | - Name of an existing IAM Role to assign to AI Unlimited, - or the name to give to the newly created role. - Leave blank to use an autogenerated name. - Requires CAPABILITY_NAMED_IAM if naming a new IAM Role. - Type: String - - IamPermissionsBoundary: - Description: | - Optional: Arn of a permissions boundary to pass to the IAM Role assigned to AI Unlimited. - Type: String - - AccessCIDR: - Description: The IP address range that can be used to communicate with the AI Unlimited instance. - Type: String - AllowedPattern: ((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2}))|^$ - ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. - - PrefixList: - Description: The PrefixList that can be used to communicate with the AI Unlimited instance. - Type: String - ConstraintDescription: must be a valid prefixlist - - SecurityGroup: - Description: The SecurityGroup that can be used to communicate with the AI Unlimited instance. - Type: String - ConstraintDescription: must be a valid securityGroup ID - -Rules: - subnetsInVpc: - Assertions: - - Assert: - Fn::EachMemberEquals: - - Fn::ValueOfAll: - - AWS::EC2::Subnet::Id - - VpcId - - !Ref Vpc - AssertDescription: The subnet you selected is not in the VPC - - instanceTypeInZone: - Assertions: - - Assert: - Fn::EachMemberEquals: - - Fn::ValueOfAll: - - AWS::EC2::Subnet::Id - - VpcId - - !Ref Vpc - AssertDescription: The subnet you selected is not in the VPC - -Conditions: - NEEDSROLE: !Equals - - !Ref IamRole - - New - - HASPUBLICIP: !Not - - !Equals - - !Ref Private - - "true" - - HASKEY: !Not - - !Equals - - !Ref KeyName - - "" - - HASCIDR: !Not - - !Equals - - !Ref AccessCIDR - - "" - - HASPREFIXLIST: !Not - - !Equals - - !Ref PrefixList - - "" - - HASSECURITYGROUP: !Not - - !Equals - - !Ref SecurityGroup - - "" - - HASCIDRORPREFIXLIST: !Or - - !Condition HASCIDR - - !Condition HASPREFIXLIST - - HASCIDRORPREFIXLISTORSECGROUP: !Or - - !Condition HASCIDR - - !Condition HASPREFIXLIST - - !Condition HASSECURITYGROUP - - USESESSIONMANAGER: !Equals - - !Ref Session - - "true" - - NEEDSROLEANDSESSIONMANAGER: !And - - !Condition NEEDSROLE - - !Condition USESESSIONMANAGER - - HASKEYANDPUBLIC: !And - - !Condition HASKEY - - !Condition HASPUBLICIP - - HASKEYANDCIDRORPREFIXLISTORSECGROUP: !And - - !Condition HASKEY - - !Condition HASCIDRORPREFIXLISTORSECGROUP - - USENEWPERSISTENTVOLUME: !Equals - - !Ref UsePersistentVolume - - New - - HASIAMPERMISSIONSBOUNDARY: !Not - - !Equals - - !Ref IamPermissionsBoundary - - "" - - HASIAMROLENAME: !Not - - !Equals - - !Ref IamRoleName - - "" - -Resources: - AiUnlimitedVolume: - DeletionPolicy: !Ref PersistentVolumeDeletionPolicy - Type: AWS::EC2::Volume - Properties: - AvailabilityZone: !Ref AvailabilityZone - Size: !Ref PersistentVolumeSize - Encrypted: true - Tags: - - Key: Name - Value: !Join - - '-' - - - !Ref AiUnlimitedName - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - Key: Usage - Value: persistent storage - Condition: USENEWPERSISTENTVOLUME - - AiUnlimitedServer: - CreationPolicy: - ResourceSignal: - Timeout: PT15M - Type: AWS::EC2::Instance - Metadata: - AWS::CloudFormation::Init: - configSets: - ai_unlimited_install: - - prepare_directory - - !If - - USENEWPERSISTENTVOLUME - - prepare_new_storage - - !Ref AWS::NoValue - - bind_storage - - mount_storage - - install_docker - - configure_ai_unlimited_service - - configure_jupyter_service - - start_ai_unlimited_service - - configure_ai_unlimited_scheduler_service - - start_ai_unlimited_scheduler_service - - start_jupyter_service - prepare_directory: - commands: - mkdir: - command: !Sub | - #!/bin/bash -xe - mkdir -p /etc/td - prepare_new_storage: - commands: - mkfs: - command: !Sub | - #!/bin/bash -xe - /usr/sbin/mkfs -t ext4 /dev/nvme1n1 - bind_storage: - commands: - fstab: - command: !Sub | - #!/bin/bash -xe - /usr/bin/echo "/dev/nvme1n1 /etc/td ext4 defaults 0 2" >> /etc/fstab - mount_storage: - commands: - mount: - command: !Sub | - #!/bin/bash -xe - /usr/bin/mount -a - install_docker: - files: - /usr/lib/systemd/system/docker-install.service: - content: !Sub | - [Unit] - Description=Install docker - - [Service] - Type=oneshot - ExecStart=/bin/bash -c "while ! dnf update; do sleep 2; done && while ! dnf install -y docker; do sleep 2; done" - RemainAfterExit=yes - - [Install] - WantedBy=multi-user.target - commands: - verify_docker: - command: !Sub | - #!/bin/bash -xe - systemctl start docker-install - systemctl start docker - systemctl enable docker - services: - systemd: - docker: - enabled: "true" - ensureRunning: "true" - configure_ai_unlimited_service: - files: - /usr/lib/systemd/system/ai-unlimited.service: - content: !Sub | - [Unit] - Description=AI Unlimited - After=docker.service - Requires=docker.service - StartLimitInterval=200 - StartLimitBurst=10 - - [Service] - TimeoutStartSec=0 - Restart=always - RestartSec=2 - ExecStartPre=-/bin/bash -c '/usr/bin/docker network create -d bridge ai_unlimited || true' - ExecStartPre=-/usr/bin/mkdir -p /etc/td/ai-unlimited - ExecStartPre=-/usr/bin/docker exec %n stop || true - ExecStartPre=-/usr/bin/docker rm %n || true - ExecStartPre=/usr/bin/docker pull teradata/ai-unlimited-workspaces:${ AiUnlimitedVersion } - ExecStart=/usr/bin/docker run \ - -e accept_license=Y \ - -e PLATFORM=aws \ - -v /etc/td/ai-unlimited:/etc/td \ - -p ${ AiUnlimitedHttpPort }:3000 \ - -p ${ AiUnlimitedGrpcPort }:3282 \ - --network ai_unlimited \ - --net-alias ${ DnsName } \ - --rm --name %n teradata/ai-unlimited-workspaces:${ AiUnlimitedVersion } workspaces serve -v - [Install] - WantedBy=multi-user.target - group: root - mode: "000400" - owner: root - start_ai_unlimited_service: - services: - systemd: - ai-unlimited: - enabled: "true" - ensureRunning: "true" - configure_ai_unlimited_scheduler_service: - files: - /usr/lib/systemd/system/ai-unlimited-scheduler.service: - content: !Sub | - [Unit] - Description=AI Unlimited Scheduler - After=ai-unlimited.service - Requires=ai-unlimited.service - StartLimitInterval=200 - StartLimitBurst=10 - - [Service] - TimeoutStartSec=0 - Restart=always - RestartSec=2 - ExecStartPre=-/usr/bin/docker exec %n stop || true - ExecStartPre=-/usr/bin/docker rm %n || true - ExecStartPre=/usr/bin/docker pull teradata/ai-unlimited-scheduler:latest - ExecStart=/usr/bin/docker run \ - --network ai_unlimited \ - -p ${ AiUnlimitedSchedulerGrpcPort }:50051 \ - -p ${ AiUnlimitedSchedulerHttpPort }:50061 \ - -v /etc/td/ai-unlimited:/etc/td \ - -e TD_WSSCHED_LOG_PATH=/etc/td/workspaces/scheduler_logs \ - -e TD_WSSCHED_TASK_LOG_PATH=/etc/td/workspaces/scheduler_logs/projects \ - -e TD_WSSCHED_POL_INTERVAL=2 \ - -e TD_WS_CONTAINER_NAME=ai-unlimited.service \ - --rm --name %n teradata/ai-unlimited-scheduler:latest workspace-event-scheduler serve - [Install] - WantedBy=multi-user.target - group: root - mode: "000400" - owner: root - start_ai_unlimited_scheduler_service: - services: - systemd: - ai-unlimited-scheduler: - enabled: "true" - ensureRunning: "true" - configure_jupyter_service: - files: - /usr/lib/systemd/system/jupyter.service: - content: !Sub | - [Unit] - Description=jupyter - After=ai-unlimited.service - Requires=ai-unlimited.service - StartLimitInterval=200 - StartLimitBurst=10 - - [Service] - TimeoutStartSec=0 - Restart=always - RestartSec=2 - ExecStartPre=-/usr/bin/docker network create -d bridge ai_unlimited - ExecStartPre=-/usr/bin/mkdir -p /etc/td/jupyter/{userdata,ipython} - ExecStartPre=-/usr/bin/docker exec %n stop || true - ExecStartPre=-/usr/bin/docker rm %n || true - ExecStartPre=/usr/bin/docker pull teradata/ai-unlimited-jupyter:${ JupyterVersion } - ExecStart=/usr/bin/docker run \ - -e accept_license=Y \ - -e JUPYTER_TOKEN=${ JupyterToken } \ - -v /etc/td/jupyter/userdata:/home/jovyan/JupyterLabRoot/userdata \ - -v /etc/td/jupyter/ipython:/home/jovyan/.ipython \ - -p ${ JupyterHttpPort }:8888 \ - --network ai_unlimited \ - --rm --name %n teradata/ai-unlimited-jupyter:${ JupyterVersion } - - [Install] - WantedBy=multi-user.target - group: root - mode: "000400" - owner: root - start_jupyter_service: - services: - systemd: - jupyter: - enabled: "true" - ensureRunning: "true" - Properties: - PropagateTagsToVolumeOnCreation: true - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - VolumeSize: !Ref RootVolumeSize - Encrypted: true - NetworkInterfaces: - - DeviceIndex: 0 - SubnetId: !Ref Subnet - GroupSet: - - !GetAtt AiUnlimitedSecurityGroup.GroupId - - !GetAtt AiUnlimitedSchedulerSecurityGroup.GroupId - - !GetAtt JupyterSecurityGroup.GroupId - AssociatePublicIpAddress: !If - - HASPUBLICIP - - true - - !Ref AWS::NoValue - ImageId: !Ref LatestAmiId - InstanceType: !Ref InstanceType - KeyName: !If - - HASKEY - - !Ref KeyName - - !Ref AWS::NoValue - DisableApiTermination: !Ref TerminationProtection - IamInstanceProfile: !Ref AiUnlimitedInstanceProfile - Volumes: - - Device: /dev/xvdb - VolumeId: !If - - USENEWPERSISTENTVOLUME - - !Ref AiUnlimitedVolume - - !Ref ExistingPersistentVolumeId - Tags: - - Key: Name - Value: !Join - - '-' - - - !Ref AiUnlimitedName - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - UserData: !Base64 - Fn::Sub: | - #!/bin/bash -xe - yum update -y - yum update -y aws-cfn-bootstrap - /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource AiUnlimitedServer --configsets ai_unlimited_install --region ${AWS::Region} - /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource AiUnlimitedServer --region ${AWS::Region} - - LoadBalancerAiUnlimitedSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server from LoadBalancer over http, grpc, and ssh - SecurityGroupIngress: - - FromPort: !Ref AiUnlimitedHttpPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedHttpPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - - FromPort: !Ref AiUnlimitedGrpcPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedGrpcPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASCIDRORPREFIXLISTORSECGROUP - - LoadBalancerSchedulerSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server from LoadBalancer over http, grpc, and ssh - SecurityGroupIngress: - - FromPort: !Ref AiUnlimitedSchedulerHttpPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedSchedulerHttpPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - - FromPort: !Ref AiUnlimitedSchedulerGrpcPort - IpProtocol: tcp - ToPort: !Ref AiUnlimitedSchedulerGrpcPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASCIDRORPREFIXLISTORSECGROUP - - LoadBalancerJupyterSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server from LoadBalancer over http, grpc, and ssh - SecurityGroupIngress: - - FromPort: !Ref JupyterHttpPort - IpProtocol: tcp - ToPort: !Ref JupyterHttpPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASCIDRORPREFIXLISTORSECGROUP - - LoadBalancer: - Type: AWS::ElasticLoadBalancingV2::LoadBalancer - Properties: - Scheme: !Ref LoadBalancerScheme - Subnets: - - !Ref LoadBalancerSubnetOne - - !Ref LoadBalancerSubnetTwo - SecurityGroups: - - !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - - !GetAtt LoadBalancerJupyterSecurityGroup.GroupId - Type: application - - AiUnlimitedHTTPListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref AiUnlimitedHTTPTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref AiUnlimitedHttpPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - JupyterHTTPListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref JupyterHTTPTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref JupyterHttpPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - AiUnlimitedSchedulerHTTPListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref AiUnlimitedSchedulerHTTPTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref AiUnlimitedSchedulerHttpPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - AiUnlimitedSchedulerGRPCListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref AiUnlimitedSchedulerGRPCTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref AiUnlimitedSchedulerGrpcPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - AiUnlimitedSchedulerHTTPTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTPS - HealthCheckTimeoutSeconds: 15 - HealthCheckPath: /healthcheck - Matcher: - HttpCode: "200" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - aisch - - ui - - http - Port: !Ref AiUnlimitedSchedulerHttpPort - Protocol: HTTP - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDWUNLIMITEDHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedSchedulerHttpPort - VpcId: !Ref Vpc - - AiUnlimitedSchedulerGRPCTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTPS - HealthCheckTimeoutSeconds: 15 - Matcher: - GrpcCode: "0" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - aisch - - api - - grpc - Port: !Ref AiUnlimitedSchedulerGrpcPort - Protocol: HTTPS - ProtocolVersion: GRPC - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDWUNLIMITEDHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedSchedulerGrpcPort - VpcId: !Ref Vpc - - AiUnlimitedHTTPTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTP - HealthCheckTimeoutSeconds: 15 - Matcher: - HttpCode: "200" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - td-aiu - - ui - - http - Port: !Ref AiUnlimitedHttpPort - Protocol: HTTP - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDWUNLIMITEDHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedHttpPort - VpcId: !Ref Vpc - - JupyterHTTPTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTP - HealthCheckTimeoutSeconds: 15 - Matcher: - HttpCode: "200" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - jupyter - - ui - - http - Port: !Ref JupyterHttpPort - Protocol: HTTP - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDJUPYTERHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref JupyterHttpPort - VpcId: !Ref Vpc - - AiUnlimitedGRPCTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTPS - HealthCheckTimeoutSeconds: 15 - HealthyThresholdCount: 5 - Matcher: - GrpcCode: "0" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - td-aiu - - api - - grpc - Port: !Ref AiUnlimitedGrpcPort - Protocol: HTTP - ProtocolVersion: GRPC - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDUNLIMITEDSGRPCSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref AiUnlimitedServer - Port: !Ref AiUnlimitedGrpcPort - VpcId: !Ref Vpc - - AiUnlimitedSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server over http and grpc - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedHttpPort - ToPort: !Ref AiUnlimitedHttpPort - SourceSecurityGroupId: !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedGrpcPort - ToPort: !Ref AiUnlimitedGrpcPort - SourceSecurityGroupId: !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedHttpPort - ToPort: !Ref AiUnlimitedHttpPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedGrpcPort - ToPort: !Ref AiUnlimitedGrpcPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - AiUnlimitedSchedulerSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to AI Unlimited server over http and grpc - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerGrpcPort - ToPort: !Ref AiUnlimitedSchedulerGrpcPort - SourceSecurityGroupId: !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerHttpPort - ToPort: !Ref AiUnlimitedSchedulerHttpPort - SourceSecurityGroupId: !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerHttpPort - ToPort: !Ref AiUnlimitedSchedulerHttpPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref AiUnlimitedSchedulerGrpcPort - ToPort: !Ref AiUnlimitedSchedulerGrpcPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - JupyterSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to jupyter server over http - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: !Ref JupyterHttpPort - ToPort: !Ref JupyterHttpPort - SourceSecurityGroupId: !GetAtt LoadBalancerJupyterSecurityGroup.GroupId - - FromPort: !Ref JupyterHttpPort - IpProtocol: tcp - ToPort: !Ref JupyterHttpPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - - SecurityGroupIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !GetAtt AiUnlimitedSecurityGroup.GroupId - FromPort: 22 - IpProtocol: tcp - ToPort: 22 - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASKEYANDCIDRORPREFIXLISTORSECGROUP - - AiUnlimitedRole: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com - Action: - - sts:AssumeRole - Path: / - RoleName: !If - - HASIAMROLENAME - - !Ref IamRoleName - - !Ref AWS::NoValue - PermissionsBoundary: !If - - HASIAMPERMISSIONSBOUNDARY - - !Ref IamPermissionsBoundary - - !Ref AWS::NoValue - Condition: NEEDSROLE - - SessionManagerPolicies: - Type: AWS::IAM::Policy - Properties: - PolicyName: !Join - - '-' - - - ai-unlimited - - session - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Action: - - ssm:DescribeAssociation - - ssm:GetDeployablePatchSnapshotForInstance - - ssm:GetDocument - - ssm:DescribeDocument - - ssm:GetManifest - - ssm:ListAssociations - - ssm:ListInstanceAssociations - - ssm:PutInventory - - ssm:PutComplianceItems - - ssm:PutConfigurePackageResult - - ssm:UpdateAssociationStatus - - ssm:UpdateInstanceAssociationStatus - - ssm:UpdateInstanceInformation - Resource: '*' - - Effect: Allow - Action: - - ssmmessages:CreateControlChannel - - ssmmessages:CreateDataChannel - - ssmmessages:OpenControlChannel - - ssmmessages:OpenDataChannel - Resource: '*' - - Effect: Allow - Action: - - ec2messages:AcknowledgeMessage - - ec2messages:DeleteMessage - - ec2messages:FailMessage - - ec2messages:GetEndpoint - - ec2messages:GetMessages - - ec2messages:SendReply - Resource: '*' - Roles: - - !Ref AiUnlimitedRole - Condition: NEEDSROLEANDSESSIONMANAGER - - AiUnlimitedRolePolicies: - Type: AWS::IAM::Policy - Properties: - PolicyName: !Join - - '-' - - - ai-unlimited - - deploy - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Action: - - iam:PassRole - - iam:AddRoleToInstanceProfile - - iam:CreateInstanceProfile - - iam:CreateRole - - iam:DeleteInstanceProfile - - iam:DeleteRole - - iam:DeleteRolePolicy - - iam:GetInstanceProfile - - iam:GetRole - - iam:GetRolePolicy - - iam:ListAttachedRolePolicies - - iam:ListInstanceProfilesForRole - - iam:ListRolePolicies - - iam:PutRolePolicy - - iam:RemoveRoleFromInstanceProfile - - iam:TagRole - - iam:TagInstanceProfile - - ec2:TerminateInstances - - ec2:RunInstances - - ec2:RevokeSecurityGroupEgress - - ec2:ModifyInstanceAttribute - - ec2:ImportKeyPair - - ec2:DescribeVpcs - - ec2:DescribeVolumes - - ec2:DescribeTags - - ec2:DescribeSubnets - - ec2:DescribeSecurityGroups - - ec2:DescribePlacementGroups - - ec2:DescribeNetworkInterfaces - - ec2:DescribeLaunchTemplates - - ec2:DescribeLaunchTemplateVersions - - ec2:DescribeKeyPairs - - ec2:DescribeInstanceTypes - - ec2:DescribeInstanceTypeOfferings - - ec2:DescribeInstances - - ec2:DescribeInstanceAttribute - - ec2:DescribeImages - - ec2:DescribeAccountAttributes - - ec2:DescribeAvailabilityZones - - ec2:DescribeManagedPrefixLists - - ec2:DescribeVpcAttribute - - ec2:DeleteTags - - ec2:DeleteSecurityGroup - - ec2:DeletePlacementGroup - - ec2:DeleteLaunchTemplate - - ec2:DeleteLaunchTemplateVersions - - ec2:DeleteKeyPair - - ec2:CreateTags - - ec2:CreateSecurityGroup - - ec2:CreatePlacementGroup - - ec2:CreateLaunchTemplateVersion - - ec2:CreateLaunchTemplate - - ec2:AuthorizeSecurityGroupIngress - - ec2:AuthorizeSecurityGroupEgress - - secretsmanager:CreateSecret - - secretsmanager:DeleteSecret - - secretsmanager:DescribeSecret - - secretsmanager:GetResourcePolicy - - secretsmanager:GetSecretValue - - secretsmanager:PutSecretValue - - secretsmanager:TagResource - - s3:CreateBucket - - s3:DeleteBucket - - s3:PutObject - - s3:GetObject - - cloudformation:CreateStack - - cloudformation:DeleteStack - - cloudformation:DescribeStacks - - cloudformation:ListStacks - - cloudformation:DescribeStackEvents - - ssm:PutParameter - - ssm:GetParameter - - ssm:DeleteParameter - - ec2:RevokeSecurityGroupIngress - - ec2:CreateInternetGateway - - ec2:CreateVpc - - ec2:DescribeInternetGateways - - ec2:DeleteVpc - - ec2:ModifyVpcAttribute - - ec2:DeleteInternetGateway - - ec2:CreateSubnet - - ec2:CreateRouteTable - - ec2:DescribeRouteTables - - ec2:DeleteSubnet - - ec2:DeleteRouteTable - - ec2:AttachInternetGateway - - ec2:ModifySubnetAttribute - - ec2:DetachInternetGateway - - ec2:AssociateRouteTable - - ec2:CreateRoute - - ec2:DisassociateRouteTable - - ec2:DeleteRoute - Resource: '*' - Roles: - - !Ref AiUnlimitedRole - Condition: NEEDSROLE - - AiUnlimitedInstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - Path: / - Roles: !If - - NEEDSROLE - - - !Ref AiUnlimitedRole - - - !Ref IamRoleName - - ACMCertificate: - Type: AWS::CertificateManager::Certificate - Properties: - DomainName: !Ref DnsName - DomainValidationOptions: - - DomainName: !Ref DnsName - HostedZoneId: !Ref HostedZoneId - ValidationMethod: DNS - - LoadBalancerDNS: - Type: AWS::Route53::RecordSetGroup - Properties: - HostedZoneId: !Ref HostedZoneId - RecordSets: - - Name: !Ref DnsName - Type: A - AliasTarget: - HostedZoneId: !GetAtt LoadBalancer.CanonicalHostedZoneID - DNSName: !GetAtt LoadBalancer.DNSName - -Outputs: - PublicIP: - Description: EC2 public IP - Value: !GetAtt AiUnlimitedServer.PublicIp - Condition: HASPUBLICIP - - PrivateIP: - Description: EC2 private IP - Value: !GetAtt AiUnlimitedServer.PrivateIp - - AiUnlimitedUiAccess: - Description: Loadbalancer access endpoint for AI Unlimited UI Access - Value: !Sub https://${ DnsName }:${ AiUnlimitedHttpPort } - - AiUnlimitedApiAccess: - Description: Loadbalancer access endpoint for AI Unlimited API Access - Value: !Sub ${ DnsName }:${ AiUnlimitedGrpcPort } - - InstanceSecurityGroups: - Description: AI Unlimited Security Group - Value: !Join - - ', ' - - - !GetAtt AiUnlimitedSecurityGroup.GroupId - - !GetAtt AiUnlimitedSchedulerSecurityGroup.GroupId - - !GetAtt JupyterSecurityGroup.GroupId - - LoadBalancerSecurityGroups: - Description: AI Unlimited Load Balancer Security Group - Value: !Join - - ', ' - - - !GetAtt LoadBalancerAiUnlimitedSecurityGroup.GroupId - - !GetAtt LoadBalancerSchedulerSecurityGroup.GroupId - - !GetAtt LoadBalancerJupyterSecurityGroup.GroupId - - PublicSshConeection: - Description: AI Unlimited ssh connnection string - Value: !Sub ssh ec2-user@${ AiUnlimitedServer.PublicIp } - Condition: HASKEYANDPUBLIC - - PrivateSshConeection: - Description: AI Unlimited ssh connnection string - Value: !Sub ssh ec2-user@${ AiUnlimitedServer.PrivateIp } - Condition: HASKEY - - PersistentVolumeId: - Description: Id of the new persistent volume created for AI Unlimited - Value: !Ref AiUnlimitedVolume - Condition: USENEWPERSISTENTVOLUME - - JupyterUIAccess: - Description: Loadbalancer access endpoint for API Access - Value: !Sub https://${ DnsName }:${ JupyterHttpPort }?token=${ JupyterToken } - - JupyterInternalAccessToAiUnlimited: - Description: AI Unlimited endpoint for local Jupyter access - Value: !Sub ai-unlimited.service:${ AiUnlimitedGrpcPort } \ No newline at end of file diff --git a/deployments/aws/templates/jupyter/jupyter-with-alb.yaml b/deployments/aws/templates/jupyter/jupyter-with-alb.yaml deleted file mode 100644 index 200cf11..0000000 --- a/deployments/aws/templates/jupyter/jupyter-with-alb.yaml +++ /dev/null @@ -1,815 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" - -Description: 'AWS CloudFormation Template jupyter: a jupyter instance configured with the ai-unlimited kernel. Note: You will be billed for the AWS resources used if you create a stack from this template.' - -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Jupyter - Parameters: - - JupyterName - - InstanceType - - RootVolumeSize - - TerminationProtection - - JupyterToken - - IamRole - - IamRoleName - - IamPermissionsBoundary - - Label: - default: Jupyter connection - Parameters: - - AvailabilityZone - - LoadBalancerScheme - - LoadBalancerSubnetOne - - LoadBalancerSubnetTwo - - Private - - Session - - Vpc - - Subnet - - KeyName - - AccessCIDR - - PrefixList - - SecurityGroup - - JupyterToken - - JupyterHttpPort - - JupyterVersion - - Label: - default: Persistent volume - Parameters: - - UsePersistentVolume - - PersistentVolumeSize - - ExistingPersistentVolumeId - - PersistentVolumeDeletionPolicy - -Parameters: - LatestAmiId: - Type: AWS::SSM::Parameter::Value - Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 - - JupyterName: - Description: The jupyter service instance name - Type: String - Default: jupyter - AllowedPattern: ^[a-zA-Z][a-zA-Z0-9-]* - ConstraintDescription: must begin with a letter and contain only alphanumeric characters. - MaxLength: "20" - MinLength: "1" - - JupyterToken: - Description: The token or password equivalent used to access Jupyter. - Type: String - NoEcho: true - AllowedPattern: ^[a-zA-Z][a-zA-Z0-9-]* - ConstraintDescription: must begin with a letter and contain only alphanumeric characters. - MaxLength: "64" - - Private: - Description: Will Jupyter be deployed in a private network without public IPs? - Type: String - AllowedValues: - - true - - false - Default: false - - LoadBalancerScheme: - Description: "If using a LoadBalancer, will it be internal or internet-facing? \nThe DNS name of an Internet-facing load balancer is publicly resolvable to the public IP addresses of the nodes.\nTherefore, Internet-facing load balancers can route requests from clients over the internet. The nodes of an \ninternal load balancer have only private IP addresses. The DNS name of an internal load balancer is publicly\nresolvable to the private IP addresses of the nodes. Therefore, internal load balancers can route requests only\nfrom clients with access to the VPC for the load balancer.\n" - Type: String - AllowedValues: - - internal - - internet-facing - Default: internet-facing - - Session: - Description: Should Jupyter be accessible via AWS Session Manager? - Type: String - AllowedValues: - - true - - false - Default: false - - Vpc: - Description: Network to deploy the jupyter service to. - Type: AWS::EC2::VPC::Id - ConstraintDescription: must be the name of an existing vpc. - - Subnet: - Description: Subnetwork to deploy the Jupyter service to. - Type: AWS::EC2::Subnet::Id - ConstraintDescription: must be the name of a existing subnet. - - AvailabilityZone: - Description: "Availability zone to deploy the Jupyter service to.\nThis must match the subnet, the zone of any pre existing volumes if used, \nand the instance type must be available in the selected zone.\n" - Type: AWS::EC2::AvailabilityZone::Name - ConstraintDescription: must be the name of a existing subnet. - - LoadBalancerSubnetOne: - Description: First subnetwork to deploy the Application Load Balancer to. - Type: AWS::EC2::Subnet::Id - - LoadBalancerSubnetTwo: - Description: Second subnetwork to deploy the Application Load Balancer to. - Type: AWS::EC2::Subnet::Id - - HostedZoneId: - Description: Zone ID of an existing Route 53 zone to add an entry for the Application Load Balancer to. - Type: AWS::Route53::HostedZone::Id - - DnsName: - Description: | - Name for Load Balancer DNS Entry, must fit as subdomain in the provides Route 53 Hosted Zone ID. - Example: jupyter.yourhostedzonedomainname.com - Type: String - - JupyterHttpPort: - Description: port to access the jupyter service ui. - Type: Number - Default: 8888 - ConstraintDescription: must be a valid ununsed port between 0 and 65535. - MinValue: 0 - MaxValue: 65535 - - JupyterVersion: - Description: Which version of jupyter to deploy, uses container version tags, defaults to "latest" - Type: String - Default: latest - - RootVolumeSize: - Description: size of the root disk to the jupyter server. - Type: Number - Default: 20 - ConstraintDescription: Size in GB, between 10 and 1000. - MinValue: 8 - MaxValue: 1000 - - UsePersistentVolume: - Description: Should we use a new or existing volume for persistent data on the jupyter server. - Type: String - AllowedValues: - - New - - Existing - Default: New - ConstraintDescription: Specify if you are using a a new persistent volume, an existing one, or none. - - PersistentVolumeSize: - Description: size of the optional persistent disk to the jupyter server. - Type: Number - Default: 20 - ConstraintDescription: Size in GB, between 10 and 1000. - MinValue: 8 - MaxValue: 1000 - - ExistingPersistentVolumeId: - Description: Id of the existing persistent volume to attach. Must be int the same availability zone as the Jupyter instance. - Type: String - Default: None - - PersistentVolumeDeletionPolicy: - Description: Behavior for the Persistent Volume when deleting the cloudformations deployment. - Type: String - AllowedValues: - - Delete - - Retain - - RetainExceptOnCreate - - Snapshot - Default: Retain - - TerminationProtection: - Description: Enable instance termination protection. - Type: String - AllowedValues: - - true - - false - Default: false - - InstanceType: - Description: jupyter EC2 instance type - Type: String - AllowedValues: - - t3.nano - - t3.micro - - t3.small - - t3.medium - - t3.large - - m3.medium - - m3.large - - m3.xlarge - - m3.2xlarge - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - - c3.large - - c3.xlarge - - c3.2xlarge - - c3.4xlarge - - c3.8xlarge - - c4.large - - c4.xlarge - - c4.2xlarge - - c4.4xlarge - - c4.8xlarge - - r3.large - - r3.xlarge - - r3.2xlarge - - r3.4xlarge - - r3.8xlarge - - i2.xlarge - - i2.2xlarge - - i2.4xlarge - - i2.8xlarge - Default: t3.micro - ConstraintDescription: must be a valid EC2 instance type. - - KeyName: - Description: Name of an existing EC2 KeyPair to enable SSH access to the instances, leave empty if no ssh keys should be included - Type: String - - IamRole: - Description: | - Create a new IAM role for jupyter or use an exiting one. - Requires CAPABILITY_IAM if creating a new IAM Role - Type: String - AllowedValues: - - None - - New - - Existing - Default: New - - IamRoleName: - Description: | - Name of an existing IAM Role to assign to Jupyter, - or the name to give to the newly created role. - Leave blank to use an autogenerated name. - Requires CAPABILITY_NAMED_IAM if naming a new IAM Role. - Type: String - - IamPermissionsBoundary: - Description: | - Optional: Arn of a permissions boundary to pass to the IAM Role assigned to Jupyter. - Type: String - - AccessCIDR: - Description: The IP address range that can be used to communicate with the juptyer instance. - Type: String - AllowedPattern: ((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2}))|^$ - ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. - - PrefixList: - Description: The PrefixList that can be used to communicate with the jupyter instance. - Type: String - ConstraintDescription: must be a valid prefixlist - - SecurityGroup: - Description: The SecurityGroup that can be used to communicate with the Jupyter instance. - Type: String - ConstraintDescription: must be a valid securityGroup ID - -Rules: - subnetsInVpc: - Assertions: - - Assert: - Fn::EachMemberEquals: - - Fn::ValueOfAll: - - AWS::EC2::Subnet::Id - - VpcId - - !Ref Vpc - AssertDescription: The subnet you selected is not in the VPC - - instanceTypeInZone: - Assertions: - - Assert: - Fn::EachMemberEquals: - - Fn::ValueOfAll: - - AWS::EC2::Subnet::Id - - VpcId - - !Ref Vpc - AssertDescription: The subnet you selected is not in the VPC - -Conditions: - NEEDSROLE: !Equals - - !Ref IamRole - - New - - HASPUBLICIP: !Not - - !Equals - - !Ref Private - - "true" - - HASKEY: !Not - - !Equals - - !Ref KeyName - - "" - - HASCIDR: !Not - - !Equals - - !Ref AccessCIDR - - "" - - HASPREFIXLIST: !Not - - !Equals - - !Ref PrefixList - - "" - - HASSECURITYGROUP: !Not - - !Equals - - !Ref SecurityGroup - - "" - - HASCIDRORPREFIXLIST: !Or - - !Condition HASCIDR - - !Condition HASPREFIXLIST - - HASCIDRORPREFIXLISTORSECGROUP: !Or - - !Condition HASCIDR - - !Condition HASPREFIXLIST - - !Condition HASSECURITYGROUP - - USESESSIONMANAGER: !Equals - - !Ref Session - - "true" - - NEEDSROLEANDSESSIONMANAGER: !And - - !Condition NEEDSROLE - - !Condition USESESSIONMANAGER - - NEEDINSTANCEPROFILE: !Or - - !Not - - !Condition NEEDSROLE - - !Condition NEEDSROLEANDSESSIONMANAGER - - HASKEYANDPUBLIC: !And - - !Condition HASKEY - - !Condition HASPUBLICIP - - HASKEYANDCIDRORPREFIXLISTORSECGROUP: !And - - !Condition HASKEY - - !Condition HASCIDRORPREFIXLISTORSECGROUP - - USENEWPERSISTENTVOLUME: !Equals - - !Ref UsePersistentVolume - - New - - HASIAMPERMISSIONSBOUNDARY: !Not - - !Equals - - !Ref IamPermissionsBoundary - - "" - - HASIAMROLENAME: !Not - - !Equals - - !Ref IamRoleName - - "" - -Resources: - JupyterVolume: - DeletionPolicy: !Ref PersistentVolumeDeletionPolicy - Type: AWS::EC2::Volume - Properties: - AvailabilityZone: !Ref AvailabilityZone - Size: !Ref PersistentVolumeSize - Encrypted: true - Tags: - - Key: Name - Value: !Join - - '-' - - - !Ref JupyterName - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - Key: Usage - Value: persistent storage - Condition: USENEWPERSISTENTVOLUME - - JupyterServer: - CreationPolicy: - ResourceSignal: - Timeout: PT15M - Type: AWS::EC2::Instance - Metadata: - AWS::CloudFormation::Init: - configSets: - jupyter_install: - - prepare_directory - - !If - - USENEWPERSISTENTVOLUME - - prepare_new_storage - - !Ref AWS::NoValue - - bind_storage - - mount_storage - - install_docker - - configure_jupyter_service - - start_jupyter_service - prepare_directory: - commands: - mkdir: - command: !Sub | - #!/bin/bash -xe - /usr/bin/mkdir -p /etc/td - prepare_new_storage: - commands: - mkfs: - command: !Sub | - #!/bin/bash -xe - /usr/sbin/mkfs -t ext4 /dev/nvme1n1 - bind_storage: - commands: - fstab: - command: !Sub | - #!/bin/bash -xe - /usr/bin/echo "/dev/nvme1n1 /etc/td ext4 defaults 0 2" >> /etc/fstab - mount_storage: - commands: - mount: - command: !Sub | - #!/bin/bash -xe - /usr/bin/mount -a - install_docker: - files: - /usr/lib/systemd/system/docker-install.service: - content: !Sub | - [Unit] - Description=Install docker - - [Service] - Type=oneshot - ExecStart=/bin/bash -c "while ! dnf update; do sleep 2; done && while ! dnf install -y docker; do sleep 2; done" - RemainAfterExit=yes - - [Install] - WantedBy=multi-user.target - commands: - verify_docker: - command: !Sub | - #!/bin/bash -xe - systemctl start docker-install - systemctl start docker - systemctl enable docker - services: - systemd: - docker: - enabled: "true" - ensureRunning: "true" - configure_jupyter_service: - files: - /usr/lib/systemd/system/jupyter.service: - content: !Sub | - [Unit] - Description=jupyter - After=docker.service - Requires=docker.service - StartLimitInterval=200 - StartLimitBurst=10 - - [Service] - TimeoutStartSec=0 - Restart=always - RestartSec=2 - ExecStartPre=-/usr/bin/docker network create -d bridge ai_unlimited - ExecStartPre=-/usr/bin/mkdir -p /etc/td/jupyter/{userdata,ipython} - ExecStartPre=-/usr/bin/docker exec %n stop || true - ExecStartPre=-/usr/bin/docker rm %n || true - ExecStartPre=/usr/bin/docker pull teradata/ai-unlimited-jupyter:${ JupyterVersion } - ExecStart=/usr/bin/docker run \ - -e accept_license=Y \ - -e JUPYTER_TOKEN=${ JupyterToken } \ - -v /etc/td/jupyter/userdata:/home/jovyan/JupyterLabRoot/userdata \ - -v /etc/td/jupyter/ipython:/home/jovyan/.ipython \ - -p ${ JupyterHttpPort }:8888 \ - --network ai_unlimited \ - --rm --name %n teradata/ai-unlimited-jupyter:${ JupyterVersion } - - [Install] - WantedBy=multi-user.target - group: root - mode: "000400" - owner: root - start_jupyter_service: - services: - systemd: - jupyter: - enabled: "true" - ensureRunning: "true" - Properties: - PropagateTagsToVolumeOnCreation: true - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - VolumeSize: !Ref RootVolumeSize - Encrypted: true - NetworkInterfaces: - - DeviceIndex: 0 - SubnetId: !Ref Subnet - GroupSet: - - !GetAtt JupyterSecurityGroup.GroupId - AssociatePublicIpAddress: !If - - HASPUBLICIP - - true - - !Ref AWS::NoValue - ImageId: !Ref LatestAmiId - InstanceType: !Ref InstanceType - KeyName: !If - - HASKEY - - !Ref KeyName - - !Ref AWS::NoValue - DisableApiTermination: !Ref TerminationProtection - IamInstanceProfile: !If - - NEEDINSTANCEPROFILE - - !Ref JupyterInstanceProfile - - !Ref AWS::NoValue - Volumes: - - Device: /dev/xvdb - VolumeId: !If - - USENEWPERSISTENTVOLUME - - !Ref JupyterVolume - - !Ref ExistingPersistentVolumeId - Tags: - - Key: Name - Value: !Join - - '-' - - - !Ref JupyterName - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - UserData: !Base64 - Fn::Sub: | - #!/bin/bash -xe - yum update -y - yum update -y aws-cfn-bootstrap - /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource JupyterServer --configsets jupyter_install --region ${AWS::Region} - /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource JupyterServer --region ${AWS::Region} - - LoadBalancerJupyterSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to Jupyter server from LoadBalancer over http, grpc, and ssh - SecurityGroupIngress: - - FromPort: !Ref JupyterHttpPort - IpProtocol: tcp - ToPort: !Ref JupyterHttpPort - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASCIDRORPREFIXLISTORSECGROUP - - LoadBalancer: - Type: AWS::ElasticLoadBalancingV2::LoadBalancer - Properties: - Scheme: !Ref LoadBalancerScheme - Subnets: - - !Ref LoadBalancerSubnetOne - - !Ref LoadBalancerSubnetTwo - SecurityGroups: - - !GetAtt LoadBalancerJupyterSecurityGroup.GroupId - Type: application - - JupyterHTTPListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref JupyterHTTPTargetGroup - LoadBalancerArn: !Ref LoadBalancer - Port: !Ref JupyterHttpPort - Protocol: HTTPS - Certificates: - - CertificateArn: !Ref ACMCertificate - - JupyterHTTPTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: HTTP - HealthCheckTimeoutSeconds: 15 - Matcher: - HttpCode: "200" - Name: !Join - - '-' - - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - - jupyter - - ui - - http - Port: !Ref JupyterHttpPort - Protocol: HTTP - TargetGroupAttributes: - - Key: stickiness.enabled - Value: true - - Key: stickiness.type - Value: app_cookie - - Key: stickiness.app_cookie.cookie_name - Value: TDJUPYTERHTTPSSESSION - - Key: deregistration_delay.timeout_seconds - Value: "20" - Targets: - - Id: !Ref JupyterServer - Port: !Ref JupyterHttpPort - VpcId: !Ref Vpc - - JupyterSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - VpcId: !Ref Vpc - GroupDescription: Enable access to jupyter server over http - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: !Ref JupyterHttpPort - ToPort: !Ref JupyterHttpPort - SourceSecurityGroupId: !GetAtt LoadBalancerJupyterSecurityGroup.GroupId - - !If - - HASSECURITYGROUP - - IpProtocol: tcp - FromPort: !Ref JupyterHttpPort - ToPort: !Ref JupyterHttpPort - SourceSecurityGroupId: !Ref SecurityGroup - - !Ref AWS::NoValue - - SecurityGroupIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !GetAtt JupyterSecurityGroup.GroupId - FromPort: 22 - IpProtocol: tcp - ToPort: 22 - CidrIp: !If - - HASCIDR - - !Ref AccessCIDR - - !Ref AWS::NoValue - SourcePrefixListId: !If - - HASPREFIXLIST - - !Ref PrefixList - - !Ref AWS::NoValue - SourceSecurityGroupId: !If - - HASSECURITYGROUP - - !Ref SecurityGroup - - !Ref AWS::NoValue - Condition: HASKEYANDCIDRORPREFIXLISTORSECGROUP - - JupyterRole: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com - Action: - - sts:AssumeRole - Path: / - Condition: NEEDSROLEANDSESSIONMANAGER - - SessionManagerPolicies: - Type: AWS::IAM::Policy - Properties: - PolicyName: !Join - - '-' - - - jupyter - - session - - !Select - - 4 - - !Split - - '-' - - !Select - - 2 - - !Split - - / - - !Ref AWS::StackId - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Action: - - ssm:DescribeAssociation - - ssm:GetDeployablePatchSnapshotForInstance - - ssm:GetDocument - - ssm:DescribeDocument - - ssm:GetManifest - - ssm:ListAssociations - - ssm:ListInstanceAssociations - - ssm:PutInventory - - ssm:PutComplianceItems - - ssm:PutConfigurePackageResult - - ssm:UpdateAssociationStatus - - ssm:UpdateInstanceAssociationStatus - - ssm:UpdateInstanceInformation - Resource: '*' - - Effect: Allow - Action: - - ssmmessages:CreateControlChannel - - ssmmessages:CreateDataChannel - - ssmmessages:OpenControlChannel - - ssmmessages:OpenDataChannel - Resource: '*' - - Effect: Allow - Action: - - ec2messages:AcknowledgeMessage - - ec2messages:DeleteMessage - - ec2messages:FailMessage - - ec2messages:GetEndpoint - - ec2messages:GetMessages - - ec2messages:SendReply - Resource: '*' - Roles: - - !Ref JupyterRole - Condition: NEEDSROLEANDSESSIONMANAGER - - JupyterInstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - Path: / - Roles: !If - - NEEDSROLEANDSESSIONMANAGER - - - !Ref JupyterRole - - - !Ref IamRoleName - Condition: NEEDINSTANCEPROFILE - - ACMCertificate: - Type: AWS::CertificateManager::Certificate - Properties: - DomainName: !Ref DnsName - DomainValidationOptions: - - DomainName: !Ref DnsName - HostedZoneId: !Ref HostedZoneId - ValidationMethod: DNS - - LoadBalancerDNS: - Type: AWS::Route53::RecordSetGroup - Properties: - HostedZoneId: !Ref HostedZoneId - RecordSets: - - Name: !Ref DnsName - Type: A - AliasTarget: - HostedZoneId: !GetAtt LoadBalancer.CanonicalHostedZoneID - DNSName: !GetAtt LoadBalancer.DNSName - -Outputs: - PublicIP: - Description: EC2 public IP - Value: !GetAtt JupyterServer.PublicIp - Condition: HASPUBLICIP - - PrivateIP: - Description: EC2 private IP - Value: !GetAtt JupyterServer.PrivateIp - - LoadBalancerJupyterUIAccess: - Description: Loadbalancer access endpoint for API Access - Value: !Sub https://${ DnsName }:${ JupyterHttpPort }?token=${ JupyterToken } - - InstanceSecurityGroups: - Description: AI Unlimited Security Group - Value: !GetAtt JupyterSecurityGroup.GroupId - - - LoadBalancerSecurityGroups: - Description: AI Unlimited Load Balancer Security Group - Value: !Join - - ', ' - - - !GetAtt LoadBalancerJupyterSecurityGroup.GroupId - - PublicSSHConeection: - Description: Jupyter ssh connnection string - Value: !Sub ssh ec2-user@${ JupyterServer.PublicIp } - Condition: HASKEYANDPUBLIC - - PrivateSSHConeection: - Description: jupyter ssh connnection string - Value: !Sub ssh ec2-user@${ JupyterServer.PrivateIp } - Condition: HASKEY - - PersistentVolumeId: - Description: Id of the new persistent volume created for Jupyter - Value: !Ref JupyterVolume - Condition: USENEWPERSISTENTVOLUME