{"id":859,"date":"2021-09-17T06:56:43","date_gmt":"2021-09-17T06:56:43","guid":{"rendered":"https:\/\/salarydistribution.com\/machine-learning\/2021\/09\/17\/launch-amazon-sagemaker-studio-from-external-applications-using-presigned-urls\/"},"modified":"2021-09-17T06:56:43","modified_gmt":"2021-09-17T06:56:43","slug":"launch-amazon-sagemaker-studio-from-external-applications-using-presigned-urls","status":"publish","type":"post","link":"https:\/\/salarydistribution.com\/machine-learning\/2021\/09\/17\/launch-amazon-sagemaker-studio-from-external-applications-using-presigned-urls\/","title":{"rendered":"Launch Amazon SageMaker Studio from external applications using presigned URLs"},"content":{"rendered":"<div id=\"\">\n<p><a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/studio.html\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SageMaker Studio<\/a> provides a single, web-based visual interface where you can perform all ML development steps, improving data science team productivity by up to 10 times. Studio gives you complete access, control, and visibility into each step required to build, train, and deploy models. You can quickly upload data, create new notebooks, train and tune models, move back and forth between steps to adjust experiments, compare results, and deploy models to production all in one place, making you much more productive. You can perform all machine learning (ML) development activities including notebooks, experiment management, automatic model creation, debugging, and model and data drift detection within Studio.<\/p>\n<p>In this post, we discuss how to launch Studio from external applications using presigned URLs.<\/p>\n<h2>Use case<\/h2>\n<p>In many organizations, data scientists and ML developers use Studio and notebook instances as a quick and easy way to directly log in into their development environment. You also might not want your data scientists to access the <a href=\"http:\/\/aws.amazon.com\/console\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Management Console<\/a> because it\u2019s primarily used by IT and DevOps administrators to monitor and manage AWS resources.<\/p>\n<p>There are two ways to launch Studio:<\/p>\n<ul>\n<li>Via the SageMaker console<\/li>\n<li>Using a presigned URL<\/li>\n<\/ul>\n<p>Using a presigned URL bypasses the console login, and allows you to open Studio with just one click.<\/p>\n<h2>Understanding the CreatePresignedDomainUrl API<\/h2>\n<p>You can <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/APIReference\/API_CreatePresignedDomainUrl.html\" target=\"_blank\" rel=\"noopener noreferrer\">create a presigned URL<\/a> for granting access to your <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/APIReference\/API_CreateDomain.html\" target=\"_blank\" rel=\"noopener noreferrer\">Studio domain<\/a> to <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/APIReference\/API_CreateUserProfile.html\" target=\"_blank\" rel=\"noopener noreferrer\">users<\/a> in your organization using the SageMaker <code>CreatePresignedDomainUrl<\/code> action. When requesting a presigned URL, the following parameters are available for you to configure:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-bash\">{\n\"DomainId\": \"string\",\n\"ExpiresInSeconds\": number,\n\"SessionExpirationDurationInSeconds\": number,\n\"UserProfileName\": \"string\"\n}<\/code><\/pre>\n<\/p><\/div>\n<p>Let\u2019s examine the parameters:<\/p>\n<ul>\n<li><strong>DomainId<\/strong> \u2013 This is a Studio domain ID (for example, <code>d-1234567890abcdef0<\/code>). Studio automatically generates this ID at the time of creation. You can retrieve the ID from the <strong>Studio Summary<\/strong> section of the Studio Control Panel.<\/li>\n<li><strong>ExpiresInSeconds<\/strong> \u2013 The number of seconds until the presigned URL expires. This value defaults to 300, and can be as low as 5 seconds.<\/li>\n<li><strong>SessionExpirationDurationInSeconds<\/strong> \u2013 The session expiration duration in seconds. This value defaults to 43200 (12 hours). This is how long the user can continue working when they open Studio.<\/li>\n<li><strong>UserProfileName<\/strong> \u2013 The name of the Studio user profile to sign in as (for example, John Doe). Added user names can be found on the Studio Control Panel.<\/li>\n<\/ul>\n<h2>Solution overview<\/h2>\n<p>In the solution, we use an <a href=\"http:\/\/aws.amazon.com\/lambda\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Lambda<\/a> function fronted by an <a href=\"https:\/\/aws.amazon.com\/api-gateway\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon API Gateway<\/a> to make a request to Studio and receive an HTTP 302 redirect to the presigned URL keeping\u00a0<code>ExpiresInSeconds<\/code> parameter to 5 seconds (the minimum). The small value of <code>ExpiresInSeconds<\/code> together with redirection to the presigned URL limits the URL to immediate use by the application and improves security. Because SageMaker is a public zone service, you can further improve security by using an <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/studio-interface-endpoint.html\" target=\"_blank\" rel=\"noopener noreferrer\">interface VPC endpoint to connect to Studio<\/a> from within your <a href=\"http:\/\/aws.amazon.com\/vpc\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Virtual Private Cloud<\/a> (Amazon VPC) instead of connecting over the internet. When you use an interface VPC endpoint (interface endpoint), communication between your VPC and Studio is conducted entirely and securely within the AWS network.<\/p>\n<p>The following diagram illustrates our solution architecture.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image001.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27603\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image001.jpg\" alt=\"\" width=\"932\" height=\"362\"><\/a><\/p>\n<h2>Prerequisites<\/h2>\n<p>You must have a Studio domain created. If you don\u2019t have one, <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/onboard-quick-start.html\" target=\"_blank\" rel=\"noopener noreferrer\">create one<\/a> before proceeding with this walkthrough. Make sure to add a user profile for testing. Note the Studio ID and user name from the Studio Control Panel.<\/p>\n<p>Now you\u2019re ready to deploy the solution.<\/p>\n<h2>Create an IAM policy for Lambda<\/h2>\n<p>On the <a href=\"http:\/\/aws.amazon.com\/iam\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Identity and Access Management<\/a> (IAM) console, you <a href=\"https:\/\/docs.aws.amazon.com\/IAM\/latest\/UserGuide\/access_policies_create-console.html\" target=\"_blank\" rel=\"noopener noreferrer\">create an IAM policy<\/a> using following JSON policy document, called <code>SageMakerPresignedUrl<\/code>. This policy allows the Lambda function to create presigned domain URLs for Studio.<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-bash\">{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"VisualEditor0\",\n            \"Effect\": \"Allow\",\n            \"Action\": \"SageMaker:CreatePresignedDomainUrl\",\n            \"Resource\": \"*\"\n        }\n    ]\n}<\/code><\/pre>\n<\/p><\/div>\n<p>You can <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/dg\/security_iam_id-based-policy-examples.html%22%20%5Cl%20%22access-tag-policy\" target=\"_blank\" rel=\"noopener noreferrer\">control access to SageMaker resources by using tags<\/a>.<\/p>\n<h2>Create an IAM service role for Lambda<\/h2>\n<p>Next, you <a href=\"https:\/\/docs.aws.amazon.com\/IAM\/latest\/UserGuide\/id_roles_create_for-service.html\" target=\"_blank\" rel=\"noopener noreferrer\">create an IAM role<\/a> called <code>LambdaSagemaker<\/code>. This service role creates presigned domain URLs for Studio.<\/p>\n<p>Attach the following policies to the role:<\/p>\n<ul>\n<li><code>AWSLambdaBasicExecutionRole<\/code><\/li>\n<li><code>SageMakerPresignedUrl<\/code><\/li>\n<\/ul>\n<p>When you add an API to your function via the Lambda console, the API Gateway console, or in an <a href=\"https:\/\/aws.amazon.com\/serverless\/sam\/\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Serverless Application Model<\/a> (AWS SAM) template, the function\u2019s resource-based policy that limits the function\u2019s access to the API is updated automatically.<\/p>\n<h2>Create and deploy a Lambda function to create a presigned URL<\/h2>\n<p>To create and deploy your Lambda function, complete the following steps:<\/p>\n<ol>\n<li>Create a <a href=\"https:\/\/docs.aws.amazon.com\/lambda\/latest\/dg\/lambda-python.html\" target=\"_blank\" rel=\"noopener noreferrer\">Python Lambda function<\/a> named <code>sm-presigned<\/code>.<\/li>\n<li>For <strong>Runtime<\/strong>, choose <strong>Python 3.8<\/strong>.<\/li>\n<li>For <strong>Execution role<\/strong>, select <strong>Use an existing role<\/strong>.<\/li>\n<li>Choose the role you created (<code>LambdaSageMaker<\/code>).<br \/><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image003.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27604\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image003.jpg\" alt=\"\" width=\"1028\" height=\"622\"><\/a><\/li>\n<li>Use the <a href=\"https:\/\/docs.aws.amazon.com\/lambda\/latest\/dg\/code-editor.html\" target=\"_blank\" rel=\"noopener noreferrer\">code editor<\/a> to replace the default Lambda handler code with the following Python code. Replace <code>SageMaker-region<\/code> with the AWS Region in which you created the SageMaker domain (for example, <code>us-west-2<\/code>). Replace the sample <code>DomainId<\/code> and <code>UserProfileName<\/code> values with the Studio ID and user name values noted in the prerequisites section.<\/li>\n<\/ol>\n<div class=\"hide-language\">\n<pre><code class=\"lang-python\">import boto3\nimport json\n\ndef lambda_handler(event, context):\n    client = boto3.client('Sagemaker', region_name=\"&lt;SageMaker-region&gt;\")\n    print(boto3.__version__)\n\n    response = client.create_presigned_domain_url(\n        DomainId='d-1234567890abcdef0',\n        UserProfileName='John Doe',\n        SessionExpirationDurationInSeconds=43200,\n        ExpiresInSeconds=5\n    )\n\n    return {\n        'statusCode': 302,\n        'headers': {\n            'Location': response['AuthorizedUrl']\n            }\n    }\n<\/code><\/pre>\n<\/p><\/div>\n<p>This sample code shows how to use a Lambda function to call the <code>create_presigned_domain_url<\/code> action to obtain a presigned URL. The function then redirects the response to the presigned URL using the <code>AuthorizedUrl<\/code> element.<\/p>\n<ol start=\"6\">\n<li>Note the Boto3 version.<\/li>\n<li>Save the changes and deploy the function.<\/li>\n<\/ol>\n<p>Support for the <code>ExpiresInSeconds<\/code> parameter of the <code>Create_presigned_domain_url<\/code> action of the SageMaker client comes with Boto3 version 1.17.0. If the default Boto3 version in Lambda is less than that, <a href=\"https:\/\/docs.aws.amazon.com\/lambda\/latest\/dg\/configuration-layers.html\" target=\"_blank\" rel=\"noopener noreferrer\">create and add a Lambda layer<\/a> to add the appropriate Boto3 deployment package to the <code>sm-presigned<\/code> function.<\/p>\n<h2>Create and deploy a REST API in API Gateway<\/h2>\n<p>In this step, we create a REST API with the GET method call for Lambda proxy integration.<\/p>\n<ol>\n<li>On the API Gateway console, <a href=\"https:\/\/docs.aws.amazon.com\/apigateway\/latest\/developerguide\/how-to-create-api.html\" target=\"_blank\" rel=\"noopener noreferrer\">create and configure a REST API<\/a> with the following settings:\n<ol type=\"a\">\n<li>For <strong>API name<\/strong>, enter <code>sm-presigned-api<\/code>.<\/li>\n<li>For <strong>Description<\/strong>, enter <code>API to trigger the sm-presigned Lambda function<\/code>.<\/li>\n<li>For <strong>Endpoint type<\/strong>, choose <strong>Edge optimized.<\/strong><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>Next, you set up the GET API method with Lambda proxy integration.<\/p>\n<ol start=\"2\">\n<li>On the <strong>Actions<\/strong> menu, choose <strong>Create method<\/strong>.<\/li>\n<li>Choose<strong> GET<\/strong> from the drop-down menu, and select the check mark icon.<\/li>\n<li>Leave <strong>Integration type<\/strong> set to <strong>Lambda Function<\/strong>.<\/li>\n<li>Select <strong>Use Lambda Proxy integration<\/strong>.<\/li>\n<li>On the <strong>Lambda Region<\/strong> drop-down menu, choose the Region where you created the <code>sm-presigned<\/code> function (for example, <code>us-west-2<\/code>).<\/li>\n<li>For <strong>Lambda Function<\/strong>, choose <code>sm-presigned<\/code> from the drop-down menu.<\/li>\n<li>Leave <strong>Use Default Timeout<\/strong> selected.<\/li>\n<li>Choose <strong>Save<\/strong>.<\/li>\n<li>Choose <strong>OK<\/strong> when prompted with <strong>Add Permission to Lambda Function<\/strong>.<br \/><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image005.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27605\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image005.jpg\" alt=\"\" width=\"1166\" height=\"487\"><\/a><\/li>\n<li><a href=\"https:\/\/docs.aws.amazon.com\/apigateway\/latest\/developerguide\/api-gateway-create-api-as-simple-proxy-for-lambda.html%22%20%5Cl%20%22api-gateway-create-api-as-simple-proxy-for-lambda-test\" target=\"_blank\" rel=\"noopener noreferrer\">Deploy and test the API<\/a> using the stage name <code>Dev<\/code>.<\/li>\n<li>Note the API\u2019s invoke URL for the next step.<\/li>\n<\/ol>\n<p>We use this serverless solution to test functionality. For added security, we recommend controlling and managing access to your API using the <a href=\"https:\/\/docs.aws.amazon.com\/apigateway\/latest\/developerguide\/apigateway-control-access-to-api.html\" target=\"_blank\" rel=\"noopener noreferrer\">API Gateway authentication and authorization method<\/a>. Only users who need to access <code>create_presigned_domain_url<\/code> should be given access to the API. You can then use mapping templates to pass user identity context information (using the <a href=\"https:\/\/docs.aws.amazon.com\/apigateway\/latest\/developerguide\/api-gateway-mapping-template-reference.html%22%20%5Cl%20%22context-variable-reference\" target=\"_blank\" rel=\"noopener noreferrer\">$context <\/a>variable) to the backend Lambda function. Use the mapped variable to create and pass <code>UserProfileName<\/code> in the function so that only the external users with a configured profile in Studio can invoke the <code>create_presigned_domain_url<\/code> method.<\/p>\n<h2>Create a sample webpage to launch Studio<\/h2>\n<p>You can use the API invoke URL created in the previous step to be redirected to Studio. The following is the sample code to invoke the URL:<\/p>\n<div class=\"hide-language\">\n<pre><code class=\"lang-html\">index.html\n&lt;form action=\"https:\/\/&lt;api-id&gt;.execute-api.&lt;api-region&gt;.amazonaws.com\/&lt;stage name&gt;\"&gt;\n    &lt;input type=\"text\" value=\"Launch SageMaker Studio from external applications\"style=\"width:500px;font-size:12px;border:3px\" &gt; &lt;br&gt;\n    &lt;input type=\"submit\" value=\"Go to Amazon SageMaker Studio\" style=\"font-size:12px;color:white;background-color:orange\"\/&gt;\n&lt;\/form&gt;\n<\/code><\/pre>\n<\/p><\/div>\n<p>Choose <strong>Go to Amazon SageMaker Studio<\/strong> to launch Studio.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image007.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27606\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image007.jpg\" alt=\"\" width=\"691\" height=\"131\"><\/a><\/p>\n<p>You can now access Studio from external applications.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image009.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27607\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/ML-2784-image009.jpg\" alt=\"\" width=\"2790\" height=\"1434\"><\/a><\/p>\n<p>You can deploy the application using the AWS SAM template available on <a href=\"https:\/\/github.com\/prabhatsharma\/sagemaker-presigned\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this post, we showed you how you can securely launch a SageMaker Studio domain through a presigned URL by choosing a custom expiration time that can be as low as 5 seconds. We created an application using a serverless architecture to handle Studio launch requests from external applications. You can use a similar architecture to connect to the Jupyter server from a notebook instance, so users don\u2019t have to go through the console to work on the notebook. To learn more, see the <a href=\"https:\/\/docs.aws.amazon.com\/sagemaker\/latest\/APIReference\/API_CreatePresignedNotebookInstanceUrl.html\" target=\"_blank\" rel=\"noopener noreferrer\">CreatePresignedNotebookInstanceUrl<\/a> documentation.<\/p>\n<hr>\n<h3>About the Authors<\/h3>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/Prabhat-Sharma.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-27609 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/Prabhat-Sharma.jpg\" alt=\"\" width=\"100\" height=\"133\"><\/a> <strong>Prabhat Sharma<\/strong>\u00a0is Specialist Solutions Architect for containers working on solving problems in the area of app dev, devops and ML. Away from professional life he loves to spend time with his family and friends.<\/p>\n<p><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/Akshara-Shah.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-27608 alignleft\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2021\/08\/31\/Akshara-Shah.jpg\" alt=\"\" width=\"100\" height=\"133\"><\/a><strong>Akshara Shah<\/strong> is a Solutions Architect at AWS. She provides strategic technical guidance to help customers design and build cloud solutions. She is currently focused on Machine Learning and Artificial Intelligence technologies.<\/p>\n<p>       <!-- '\"` -->\n      <\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/aws.amazon.com\/blogs\/machine-learning\/launch-amazon-sagemaker-studio-from-external-applications-using-presigned-urls\/<\/p>\n","protected":false},"author":0,"featured_media":860,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/859"}],"collection":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/comments?post=859"}],"version-history":[{"count":0,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/859\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media\/860"}],"wp:attachment":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media?parent=859"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/categories?post=859"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/tags?post=859"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}