Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Allow Sagemaker Appstream workspaces to autostop #689

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,16 @@ class AwsAccountUpdateContent extends React.Component {
};

render() {
const { isUpdateStep } = this.getStep();
let shouldDisableDoneButton = this.shouldShowWarning && !this.warningAcknowledged;
if (isAppStreamEnabled) {
shouldDisableDoneButton =
shouldDisableDoneButton || !this.accessAppStreamAcknowledged || !this.startedAppStreamFleetAcknowledged;
// No acknowledgements is necessary if we're just updating the preexisting AppStream account
if (isUpdateStep) {
shouldDisableDoneButton = false;
} else {
shouldDisableDoneButton =
shouldDisableDoneButton || !this.accessAppStreamAcknowledged || !this.startedAppStreamFleetAcknowledged;
}
}
return (
<Container className="mt3 animated fadeIn">
Expand Down Expand Up @@ -202,15 +208,21 @@ class AwsAccountUpdateContent extends React.Component {
);
}

renderSteps() {
getStep() {
// We need to determine if this is for creating the stack or updating the stack
const form = this.form;
const stackInfo = this.stackInfo;
const { hasUpdateStackUrl } = stackInfo;
const field = form.$('createOrUpdate');
const update = field.value === 'update';
const isUpdateStep = field.value === 'update';
const hasAdminAccess = form.$('managed').value === 'admin';

return { isUpdateStep, hasAdminAccess, hasUpdateStackUrl, field };
}

renderSteps() {
const { isUpdateStep, hasAdminAccess, hasUpdateStackUrl, field } = this.getStep();

return (
<>
<div className="flex justify-between pt3 pb0 pr3 pl1">
Expand All @@ -219,9 +231,9 @@ class AwsAccountUpdateContent extends React.Component {
</Header>
{hasUpdateStackUrl && <YesNo field={field} className="mb0 mt0" />}
</div>
{!update && hasAdminAccess && this.renderCreateSteps()}
{update && hasAdminAccess && this.renderUpdateSteps()}
{!hasAdminAccess && this.renderEmailTemplate(update)}
{!isUpdateStep && hasAdminAccess && this.renderCreateSteps()}
{isUpdateStep && hasAdminAccess && this.renderUpdateSteps()}
{!hasAdminAccess && this.renderEmailTemplate(isUpdateStep)}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,30 @@ Resources:
- !Ref SageMakerSecurityGroup
VpcId: !Ref VPC

SagemakerApiEndpoint:
Type: 'AWS::EC2::VPCEndpoint'
Condition: isAppStream
Properties:
SubnetIds:
- !Ref PrivateWorkspaceSubnet
VpcEndpointType: Interface
PrivateDnsEnabled: true
ServiceName: !Sub "com.amazonaws.${AWS::Region}.sagemaker.api"
VpcId: !Ref VPC
SecurityGroupIds:
- !Ref SagemakerApiEndpointSecurityGroup

SagemakerApiEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Condition: isAppStream
Properties:
GroupDescription: 'Sagemaker Api Endpoint Security Group for interface endpoint'
GroupName: 'Sagemaker-API-SG'
VpcId: !Ref VPC
SecurityGroupIngress:
- SourceSecurityGroupId: !GetAtt VPC.DefaultSecurityGroup
IpProtocol: '-1'

SageMakerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Condition: isAppStream
Expand Down Expand Up @@ -915,6 +939,13 @@ Outputs:
Export:
Name: !Join ['', [Ref: Namespace, '-SageMakerVPCE']]

SageMakerApiSG:
Description: SageMaker API SG
Condition: isAppStream
Value: !Ref SagemakerApiEndpointSecurityGroup
Export:
Name: !Join ['', [Ref: Namespace, '-SageMakerApiSecurityGroup']]

Route53HostedZone:
Description: Route53 hosted zone
Condition: isAppStreamAndCustomDomain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ Resources:
FromPort: 443
ToPort: 443
CidrIp: !Ref AccessFromCIDRBlock

SecurityGroupEgress:
- !If
- AppStreamEnabled
- DestinationSecurityGroupId:
Fn::ImportValue: !Sub "${SolutionNamespace}-SageMakerApiSecurityGroup"
IpProtocol: '-1'
- !Ref "AWS::NoValue"
PreSignedURLBoundary:
Type: AWS::IAM::ManagedPolicy
Condition: AppStreamEnabled
Expand Down
1 change: 1 addition & 0 deletions main/solution/backend/config/infra/functions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ envStatusPollHandler:
description: 'Invokes the lambda function that polls and synchronize environment status.'
environment:
APP_CUSTOM_USER_AGENT: ${self:custom.settings.customUserAgent}
APP_IS_APP_STREAM_ENABLED: ${self:custom.settings.isAppStreamEnabled}

dataSourceReachabilityHandler:
handler: src/lambdas/data-source-reachability/handler.handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ Resources:
- Effect: Allow
Action:
- ec2:AuthorizeSecurityGroupIngress
- ec2:AuthorizeSecurityGroupEgress
- ec2:RevokeSecurityGroupEgress
- ec2:CreateSecurityGroup
- ec2:DeleteSecurityGroup
Expand Down