{ "cells": [ { "cell_type": "markdown", "id": "adca95b1", "metadata": {}, "source": [ "# Connecting to Forecast Services via Virtual Private Cloud (VPC) Endpoints\n", "\n", "\n", "We are excited to announce that Amazon Forecast is now integrated as an AWS service within AWS PrivateLink. Through this integration, you can now easily provision Amazon Forecast interface endpoints within your own Virtual Private Cloud (VPC) and create connections to Amazon Forecast without needing access to the public internet. This is beneficial to customers with strict security or network requirement that restricts them from sending data over public internet.\n", "\n", "In addition, you can access additional access controls for services with VPC endpoints through usage of VPC endpoint policies, which will not override or replace the calling identity's IAM permissions, but be enforced in conjunction with the IAM permissions to allow additional control for the VPC owner. For example, if you want to only allow `ListDatasets` action when users within the VPC wants to hit Forecast service through the VPC endpoint, you can define a VPC endpoint policy such that only `ListDatasets` operation is allowed for all connections through the VPC endpoint, without the need of restricting each user's IAM permissions to do so. \n", "\n", "With today's launch, we are offering the following endpoint services for Amazon Forecast\n", "\n", "1. A VPC endpoint service to use with Amazon Forecast operations. For most users, this is the most suitable type of VPC endpoint service to establish endpoint connections to.\n", " - `com.amazonaws..forecast`\n", " - `com.amazonaws..forecastquery`\n", "1. A VPC endpoint service for Amazon Forecast operations with endpoints that comply with the Federal Information Processing Standard (FIPS) Publication 140-2 US government standard (availble in select regions only, see https://docs.aws.amazon.com/general/latest/gr/forecast.html for regions with support for FIPS endpoints)\n", " - `com.amazonaws..forecast-fips`\n", " - `com.amazonaws..forecastquery-fips`\n", "\n", "In this guide, we provide a step-by-step guide on how to connect to Amazon Forecast via VPC endpoints. First, we will cover some terminology.\n", "\n", "\n", "## Terminology\n", "\n", "The following terminology is helpful for readers to understand what VPC related components are, and will aid reader with understanding the rest of the guide.\n", "\n", "- **Private DNS**: This is a feature offered by VPC and AWS PrivateLink to allow users to easily provision changes to your own Route53 Private Hosted Zones to connect to an internal service or PrivateLink based services, including Amazon Forecast's PrivateLink enabled services. During this guide, we will showcase how to enable private DNS such that clients minimize code changes and still be able to call Forecast through VPC. More details about PrivateDNS at https://aws.amazon.com/about-aws/whats-new/2020/01/aws-privatelink-supports-private-dns-names-internal-3rd-party-services/\n", "- **VPC**: A VPC (Virtual Private Cloud) is a logically isolated virtual network that allows you control the virtual networking environment. See https://aws.amazon.com/vpc/ for more details.\n", "- **VPC Endpoint**: A VPC endpoint enables connections between a virtual private cloud (VPC) and supported services, without requiring that you use an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. We will be creating VPC endpoints to Amazon Forecast services within this guide. For more details on VPC endpoints, see https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints.html\n", "- **VPC Endpoint Policy**: A VPC endpoint policy is an IAM resource policy that you can attach to a VPC endpoint, and it allows you to control access to the service that you're connecting to. We will be exploring usage of the VPC endpoint policies in this guide. Fore more details on VPC endpoint policies, see https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html. You can also see list of sample policies at https://docs.aws.amazon.com/forecast/latest/dg/vpc-interface-endpoints.html\n", "\n", "## Overview of Guide\n", "\n", "This guide is splitted into 2 parts.\n", "\n", "Part 1 of this guide aims to walk the user through the VPC endpoint creation process, as well as setting up related infrastructure for testing purpose. Towards the end of this guide, you will have VPC endpoints available for connecting to Amazon Forecast services via VPC. You can use these VPC endpoints in various ways such as within Lambdas, EC2s, a SageMaker notebook, etc. \n", "\n", "Part 2 of this guide is available in Jupyter Notebook at https://github.com/aws-samples/amazon-forecast-samples/tree/main/notebooks/advanced/VPC_PrivateLink/Connect_Via_VPC_Endpoint_Guide.ipynb. The notebook will help reader understand how to configure AWS clients to connect to the VPC endpoints, what VPC endpoint policy can control, and how to verify that a call is going through VPC endpoint. Note that although we are connecting to Forecast through VPC via Jupyter notebook, you can do similar thing with compute resources inside a VPC such as Lambda, EC2, etc. The general concept of the notebook should still be applicable\n", "\n", "Disclaimers:\n", "- The configuration values used for creation of resources within this guide are for example purpose only. We strongly encourage you to read through the AWS docs to choose the right configuration values for production usage.\n", "- Note that the screenshots used in the notebook may be slightly different depending on the console version, but the general instructions should still be applicable.\n" ] }, { "cell_type": "markdown", "id": "7cddb204", "metadata": {}, "source": [ "## Part 1: VPC Related Setup \n", "\n", "We will be creating some VPC related resources such as VPC, and VPC endpoints to test VPC connections to Amazon Forecast's PrivateLink enabled services. The configuration values used for creation of these resources are for this sample guide purpose only. We strongly encourage you to read through the AWS docs to choose the right configuration values for production usage. If you have existing VPC/subnet/security groups you wish to use, feel free to do so as well.\n", "\n", "We will also be creating resources in `us-west-2` region. But feel free to create the resources in any Forecast supported regions of your choosing, just be sure to use consistent region throughout the guide" ] }, { "cell_type": "markdown", "id": "5ff8ac62", "metadata": {}, "source": [ "### Create VPC\n", "\n", "1. Go to AWS Console\n", "1. Select the appropriate region on the top right (`us-west-2` for purpose of this guide)\n", "1. Head to `VPC` console page\n", "1. Click on `Your VPCs` on the left navigation panel\n", "1. Click on `Create VPC`\n", "1. For the purpose of the guide, we will be using the sample configuration values for the VPC below\n", " - Populate `Name tag` field with `private-link-test-vpc`\n", " - Choose `IPv4 CIDR maunal input` and populate CIDR block with `10.0.0.0/24`\n", " - Choose `No IPv6 CIDR block`\n", " - Choose Tenancy as `Default`\n", " - Your screen should look similar to ![Create VPC](./images/CreateVPC.png)\n", " - Click `Create VPC`\n", "1. Wait till your VPC is in `available` state\n", "1. The following step is only required if we are planning to enable PrivateDNS, which we do plan to do in this guide. Select the VPC you just created\n", " - Make sure `DNS hostnames` shows `Enabled`. If not, click `Actions`, click `Edit DNS hostnames`, make sure to check `Enable`, and click `Save changes`\n", " - Make sure `DNS resolution` shows `Enabled`. If not, click `Actions`, click `Edit DNS resolution`, make sure to check `Enable` and click `Save changes`" ] }, { "cell_type": "markdown", "id": "1cf03752", "metadata": {}, "source": [ "### Create Subnet\n", "\n", "1. Head back to `VPC` console page\n", "1. Click on `Subnets` on the left navigation panel\n", "1. Click on `Create subnet`\n", "1. For the purpose of this guide, we will be using the sample configuration values for the subnet below\n", " - Select the VPC tagged with `private-link-test-vpc` as the VPC to use under VPC ID\n", " - Populate `private-link-test-subnet-01` under `Subnet name`\n", " - Choose `us-west-2a` as the `Availability Zone`\n", " - Populate `10.0.0.0/24` as the `IPv4 CIDR block`\n", " - Your screen should look similar to ![Create Subnet](./images/CreateSubnet.png)\n", " - Click `Create subnet`\n", "1. Wait till the subnet is in `available` state\n", "1. Note that best practice is usually to create multiple subnets under multiple AZs, but for purpose of this guide, we will just be creating one subnet" ] }, { "cell_type": "markdown", "id": "5c2ceb63", "metadata": {}, "source": [ "### Create Security Group\n", "\n", "1. Head back to `VPC` console page\n", "1. Click on `Security Groups` on the left navigation panel\n", "1. Click on `Create security group`\n", "1. For the purpose of the guide, we will be using the sample configuration values for the security group below\n", " - Populate `private-link-test-securty-group` as the `Security group name`\n", " - Populate `Allow inbound and outbound HTTPS connections for private link testing purpose` in the `Description`\n", " - Be sure to select the right VPC ID corresponding to VPC tagged with `private-link-test-vpc`\n", " - Click `Add rule` under `Inbound rules`\n", " - Select `HTTPS` as `Type`\n", " - Select `Anywhere-IPv4` as the `Source`\n", " - Modify the rule under `Outbound rules`\n", " - Select `HTTPS` as `Type`\n", " - Select `Anywhere-IPv4` as the `Source`\n", " - Your screen should look similar to ![Create Security Group](./images/CreateSecurityGroup.png)\n", " - Click `Create security group`" ] }, { "cell_type": "markdown", "id": "06f852e4", "metadata": {}, "source": [ "### Create VPC endpoints\n", "\n", "As of January 2022, you can create two types of Amazon VPC endpoints to use with Amazon Forecast:\n", "\n", "1. A VPC endpoint to use with Amazon Forecast operations. For most users, this is the most suitable type of VPC endpoint.\n", " - `com.amazonaws..forecast`\n", " - `com.amazonaws..forecastquery`\n", "1. A VPC endpoint for Amazon Forecast operations with endpoints that comply with the Federal Information Processing Standard (FIPS) Publication 140-2 US government standard (availble in select regions only, see https://docs.aws.amazon.com/general/latest/gr/forecast.html for regions with support for FIPS endpoints)\n", " - `com.amazonaws..forecast-fips`\n", " - `com.amazonaws..forecastquery-fips`\n", " \n", "For the purpose of this guide, we will choose the most common and standard regular endpoints instead of the FIPS endpoints.\n", "\n", "In the below steps, we will be creating the VPC endpoints that will be used for connecting traffic destined for the VPC to the Amazon Forecast services without going through the public internet.\n", "\n", "1. Head back to `VPC` console page\n", "1. Click on `Endpoints` on the left navigation panel\n", "1. Click on `Create endpoint`\n", "1. Create endpoint for `com.amazonaws.us-west-2.forecast` with values below\n", " - Select `AWS services` under `Service Category`\n", " - Under `Services`, populate the `Filter services` textbox with search term `forecast`\n", " - Select `com.amazonaws.us-west-2.forecast`\n", " - Under `VPC`, select the VPC ID corresponding to VPC tagged with `private-link-test-vpc`\n", " - Under `VPC`, expand the additional settings, be sure to uncheck `Enable DNS` name for now. This is to disable privateDNS support for now, we will enable it in later section of the guide\n", " - Under `Subnet`, select `us-west-2a` as the Availability Zone, and select the subnet id corresponding to `private-link-test-subnet-01`\n", " - Under `Security Groups`, select security group corresponding to `private-link-test-securty-group`\n", " - Under `Policy`, select `Custom` and add the following policy (we will change it to Full Access in later section):\n", " ```json\n", " {\n", " \"Statement\": [\n", " {\n", " \"Principal\": \"*\",\n", " \"Effect\": \"Allow\",\n", " \"Action\": [\n", " \"forecast:ListDatasets\"\n", " ],\n", " \"Resource\": \"*\"\n", " }\n", " ]\n", " }\n", " ```\n", " - This custom policy will allow connections through the VPC endpoint with ListDatasets action. All other actions are not allowed.\n", " - We will change it to Full Access in later section of this guide\n", " - Your screen should look similar to ![Create Forecast Endpoint 1](./images/CreateForecastEndpoint1.png) and ![Create Forecast Endpoint 2](./images/CreateForecastEndpoint2.png)\n", " - Click `Create endpoint`\n", " - Select the endpoint you just created, and wait to use it until the status changes to `Available`\n", "1. Repeat above steps but create endpoint for `com.amazonaws.us-west-2.forecast-query` with differences below\n", " - Select `com.amazonaws.us-west-2.forecast-query` as the service\n", " - Leave `Enable DNS` name checked to enable PrivateDNS support\n", " - Select `Full access` under `Policy` to allow Full access\n", " - Your screen should look similar to ![Create Forecast Query Endpoint](./images/CreateForecastQueryEndpoint.png)\n", " - Click `Create endpoint`\n", " - Select the endpoint you just created, and wait to use it until the status changes to `Available`" ] }, { "cell_type": "markdown", "id": "5bf6aa38", "metadata": {}, "source": [ "## Part 2: Demo Usage of VPC endpoints via Notebook\n", "\n", "The VPC endpoints we created in steps above are now available for your usage. You can use these VPC endpoints in various ways such as within Lambdas, EC2s, a SageMaker notebook, etc. \n", "\n", "For the purpose of the guide, we have prepared a Jupyter Notebook to demonstrate the second part of this guide at https://github.com/aws-samples/amazon-forecast-samples/tree/main/notebooks/advanced/VPC_PrivateLink/Connect_Via_VPC_Endpoint_Guide.ipynb. The notebook will help reader understand how to configure AWS clients to connect to the VPC endpoints, what VPC endpoint policy can control, and how to verify that a call is going through VPC endpoint. Note that although we are connecting to Forecast through VPC via Jupyter notebook, you can do similar thing with compute resources inside a VPC such as Lambda, EC2, etc. The general concept of the notebook should still be applicable.\n", "\n", "Please continue the guide through the Jupyter notebook" ] }, { "cell_type": "markdown", "id": "e1c1263d", "metadata": {}, "source": [ "### Notebook Related Setup \n", "\n", "#### Create Notebook Instance within VPC\n", "We will be creating a new notebook instance within a VPC. Be sure to relaunch this jupyter notebook within the newly launched notebook instance afterwards\n", "\n", "1. Go to AWS Console\n", "1. Select the appropriate region on the top right (`us-west-2` for purpose of this guide)\n", "1. Head to `Amazon SageMaker` console page\n", "1. Clck `Notebook instances` under `Notebook` on left navigation panel\n", "1. Click `Create notebook instance`\n", "1. For the purpose of the guide, we will be using the sample configuration values for the security group below\n", " - Populate `private-link-test-notebook` under `Notebook instance name`\n", " - Select `ml.t2.medium` as `Notebook instance type`\n", " - Select `notebook-al2-v1` as the `Platform identifier`\n", " - Under IAM role, feel free to create role or reusing existing role, and restrict access if needed. For guide purpose, will proceed with `Any S3 bucket access`.\n", " - Expand `Network` tab\n", " - Select VPC ID corresponding to VPC tagged with `private-link-test-vpc`\n", " - Select Subnet corresponding to subnet tagged with `private-link-test-subnet-01`\n", " - Select Security Group corresponding to security group tagged with `private-link-test-security-group`\n", " - Select `Enable — Access the internet directly through Amazon SageMaker` since within notebook, we will need access to the git hub repository, S3, IAM, etc. Be sure to look at https://docs.aws.amazon.com/sagemaker/latest/dg/appendix-notebook-and-internet-access.html if you want to choose `Disable` to restrict the notebook to connect through VPC only. For purpose of this guide, we will choose `Enable` option.\n", " - Expand `Git repositories`\n", " - Select `Clone a public Git repository to this notebook isntance only`\n", " - Populate `https://github.com/aws-samples/amazon-forecast-samples.git` under `Git repository URL` to copy contents of https://github.com/aws-samples/amazon-forecast-samples\n", " - Your screen should look similar to ![Create Notebook Instance](./images/CreateNotebookInstance.png)\n", " - Click `Create notebook instance`\n", "1. Wait for the notebook to be created and status updates to `InService`. If status is at `Stopped`, just select it, click `Actions`, and click `Start`\n", "1. Click Open Jupyter\n", "1. Navigate to this notebook under `notebooks -> advanced -> VPC_PrivateLink -> Connect_Via_VPC_Guide.ipynb`\n", "1. Be sure you have relaunched this notebook under the Notebook instance created above\n" ] }, { "cell_type": "markdown", "id": "bd1346b1", "metadata": {}, "source": [ "#### Setup the IAM permission for the SageMaker Role\n", "1. Go to IAM console\n", "1. Select the SageMaker role that was created above\n", "1. Click `Add in-line policy` to attach a new in-line policy with the below JSON. Be sure to replace `` with your AWS account ID. You can name the in-line policy with something like `test-private-link-forecast-and-iam-policy`\n", "```json\n", "{\n", " \"Version\": \"2012-10-17\",\n", " \"Statement\": [\n", " {\n", " \"Effect\": \"Allow\",\n", " \"Action\": [\n", " \"forecast:*\"\n", " ],\n", " \"Resource\": \"*\"\n", " },\n", " {\n", " \"Effect\": \"Allow\",\n", " \"Action\": [\n", " \"iam:PassRole\"\n", " ],\n", " \"Resource\": \"arn:aws:iam:::role/ForecastNotebookRole-Basic\",\n", " \"Condition\": {\n", " \"StringEquals\": {\n", " \"iam:PassedToService\": \"forecast.amazonaws.com\"\n", " }\n", " }\n", " },\n", " {\n", " \"Effect\": \"Allow\",\n", " \"Action\": [\n", " \"iam:CreateRole\",\n", " \"iam:GetRole\"\n", " ],\n", " \"Resource\": \"arn:aws:iam:::role/ForecastNotebookRole-Basic\"\n", " }\n", " ]\n", "}\n", "```" ] }, { "cell_type": "markdown", "id": "291f9e7d", "metadata": {}, "source": [ "### Familiarize Yourself with Forecast Quick Start Guide \n", "This notebook assumes you have walked through the Forecast Quick Start Guide at https://github.com/aws-samples/amazon-forecast-samples/blob/main/notebooks/basic/Getting_Started/Amazon_Forecast_Quick_Start_Guide.ipynb and understand the general Forecast creation process. The Quick Start Guide notebook will walkthrough the detailed dataset creation, dataset importing, training of predictor, and generation of Forecast, which we will assume you have seen already through the rest of this guide.\n", "\n", "If you have not done so, please go through the Quick Start Guide" ] }, { "cell_type": "markdown", "id": "fdd6a2fb", "metadata": {}, "source": [ "### Environment Setup " ] }, { "cell_type": "markdown", "id": "3b0d9cc7", "metadata": {}, "source": [ "#### Install necessary libraries (execute if necessary, such as if imports below fails)" ] }, { "cell_type": "code", "execution_count": 11, "id": "6e681b5a", "metadata": {}, "outputs": [], "source": [ "# %%capture --no-stderr setup\n", "\n", "# !pip install pandas s3fs matplotlib ipywidgets\n", "# !pip install boto3 --upgrade\n", "# !pip install tqdm\n", "\n", "# %reload_ext autoreload" ] }, { "cell_type": "markdown", "id": "da92d56d", "metadata": {}, "source": [ "#### Setup Imports" ] }, { "cell_type": "code", "execution_count": 2, "id": "df46168c", "metadata": {}, "outputs": [], "source": [ "import sys\n", "import os\n", "import shutil\n", "import datetime\n", "\n", "import pandas as pd\n", "import numpy as np\n", "import boto3\n", "\n", "# importing forecast notebook utility from notebooks/common directory\n", "sys.path.insert( 0, os.path.abspath(\"../../common\") )\n", "import util\n", "\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline \n", "plt.rcParams['figure.figsize'] = (15.0, 5.0)" ] }, { "cell_type": "markdown", "id": "cb8ba788", "metadata": {}, "source": [ "#### Create a session within specified region" ] }, { "cell_type": "code", "execution_count": 4, "id": "4dc55b2a", "metadata": {}, "outputs": [], "source": [ "region = 'us-west-2'\n", "session = boto3.Session(region_name=region)" ] }, { "cell_type": "markdown", "id": "b98c8eb1", "metadata": {}, "source": [ "#### Setup IAM Role used by Amazon Forecast to access your data" ] }, { "cell_type": "code", "execution_count": 12, "id": "5d74182e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Creating Role ForecastNotebookRole-Basic...\n", "The role ForecastNotebookRole-Basic already exists, skipping creation\n", "Done.\n", "Success! Created role = ForecastNotebookRole-Basic\n" ] } ], "source": [ "role_name = \"ForecastNotebookRole-Basic\"\n", "print(f\"Creating Role {role_name}...\")\n", "role_arn = util.get_or_create_iam_role( role_name = role_name )\n", "\n", "# echo user inputs without account\n", "print(f\"Success! Created role = {role_arn.split('/')[1]}\")" ] }, { "cell_type": "markdown", "id": "0755e2a8", "metadata": {}, "source": [ "#### Upload S3 file under unique bucket name" ] }, { "cell_type": "code", "execution_count": 6, "id": "71e067a9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
timestampitem_idtarget_value
02017-12-01 00:00:00427
12017-12-01 00:00:00736
22017-12-01 00:00:00102
\n", "
" ], "text/plain": [ " timestamp item_id target_value\n", "0 2017-12-01 00:00:00 4 27\n", "1 2017-12-01 00:00:00 7 36\n", "2 2017-12-01 00:00:00 10 2" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Enter S3 bucket name for uploading the data and hit ENTER key:private-link-test-s3-20220127\n", "\n", "Attempting to upload the data to the S3 bucket 'private-link-test-s3-20220127' at key 'data/taxi-dec2017-jan2019.csv' ...\n", "\n", "Done, the dataset is uploaded to S3 at s3://private-link-test-s3-20220127/data/taxi-dec2017-jan2019.csv.\n" ] } ], "source": [ "key=\"data/taxi-dec2017-jan2019.csv\"\n", "\n", "taxi_df = pd.read_csv(key, dtype = object, names=['timestamp','item_id','target_value'])\n", "\n", "display(taxi_df.head(3))\n", "\n", "bucket_name = input(\"\\nEnter S3 bucket name for uploading the data and hit ENTER key:\")\n", "print(f\"\\nAttempting to upload the data to the S3 bucket '{bucket_name}' at key '{key}' ...\")\n", "\n", "s3 = session.resource('s3')\n", "bucket = s3.Bucket(bucket_name)\n", "if not bucket.creation_date:\n", " if region != \"us-east-1\":\n", " s3.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={'LocationConstraint': region})\n", " else:\n", " s3.create_bucket(Bucket=bucket_name)\n", "\n", "s3.Bucket(bucket_name).Object(key).upload_file(key)\n", "ts_s3_path = f\"s3://{bucket_name}/{key}\"\n", "\n", "print(f\"\\nDone, the dataset is uploaded to S3 at {ts_s3_path}.\")" ] }, { "cell_type": "markdown", "id": "96dedce8", "metadata": {}, "source": [ "### Testing Forecast APIs through VPC \n", "\n", "We will walk through testing of Forecast APIs through the VPC. Be sure to have the VPC setups in Part 1 completed." ] }, { "cell_type": "markdown", "id": "8fee1ce9", "metadata": {}, "source": [ "#### Testing existing public DNS without VPC\n", "\n", "Since we have not turned on privateDNS for the `com.amazonaws.us-west-2.forecast` VPC endpoint. The action below succceeds because we're using a sageMaker with internet access, and the connection is going through the non-VPC public DNS `forecast.us-west-2.amazonaws.com` to make connection to Forecast service" ] }, { "cell_type": "code", "execution_count": 63, "id": "496ae661", "metadata": {}, "outputs": [], "source": [ "forecast = session.client(service_name='forecast')" ] }, { "cell_type": "code", "execution_count": 64, "id": "fea4daa2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Predictors': [{'PredictorArn': 'arn:aws:forecast:us-west-2:282494629315:predictor/TAXI_PREDICTOR_01FTHF1KK7E6VVR676WVN24MXC',\n", " 'PredictorName': 'TAXI_PREDICTOR',\n", " 'DatasetGroupArn': 'arn:aws:forecast:us-west-2:282494629315:dataset-group/TAXI_DEMO_PRIVATE_LINK',\n", " 'IsAutoPredictor': True,\n", " 'Status': 'ACTIVE',\n", " 'CreationTime': datetime.datetime(2022, 1, 28, 23, 6, 37, 563000, tzinfo=tzlocal()),\n", " 'LastModificationTime': datetime.datetime(2022, 1, 31, 18, 42, 0, 881000, tzinfo=tzlocal())}],\n", " 'ResponseMetadata': {'RequestId': '60fb2632-5fe1-405a-b322-89de9f20c586',\n", " 'HTTPStatusCode': 200,\n", " 'HTTPHeaders': {'date': 'Mon, 31 Jan 2022 19:56:41 GMT',\n", " 'content-type': 'application/x-amz-json-1.1',\n", " 'content-length': '370',\n", " 'connection': 'keep-alive',\n", " 'x-amzn-requestid': '60fb2632-5fe1-405a-b322-89de9f20c586'},\n", " 'RetryAttempts': 0}}" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "forecast.list_predictors()" ] }, { "cell_type": "markdown", "id": "1fa3bc83", "metadata": {}, "source": [ "#### Testing new VPC specific endpoints\n", "\n", "We will now start testing connection through a VPC endpoint.\n", "\n", "Because we didn't enable privateDNS for the `com.amazonaws.us-west-2.forecast` VPC endpoint, we will have to go find the VPC specific DNS that the PrivateLink generated for us. You can find it by going to the VPC console, and clicking the VPC endpoint we just created for `com.amazonaws.us-west-2.forecast`. Locate the DNS under section similar to ![VPC specific DNS](./images/VpcSpecificDNS.png)\n", "\n", "The DNS is VPC endpoint specific, so the one in this guide will not be completely same as yours, but it should be similar. \n", "\n", "Populate the DNS below with prefix `https://`" ] }, { "cell_type": "code", "execution_count": 17, "id": "895ee26e", "metadata": {}, "outputs": [], "source": [ "# With non-private VPC DNS\n", "forecast_dns = \"https://vpce-0e328db54a7a149fa-j82j07dz.forecast.us-west-2.vpce.amazonaws.com\";" ] }, { "cell_type": "code", "execution_count": 20, "id": "7532473d", "metadata": {}, "outputs": [], "source": [ "forecast = session.client(service_name='forecast',\n", " region_name=region,\n", " endpoint_url=forecast_dns\n", ")" ] }, { "cell_type": "markdown", "id": "ff4fcba6", "metadata": {}, "source": [ "**Explain**\n", "\n", "The call below is expected to fail because the VPCE policy that we defined above only allows `ListDatasets` action. However, since we know VPCE policy is only attached to the VPC endpoint, we can assure ourselves that the call is going through the VPC endpoint. What we learned is a simple way of checking that we are making network calls through the VPC endpoint" ] }, { "cell_type": "code", "execution_count": 28, "id": "b5e52514", "metadata": {}, "outputs": [ { "ename": "ClientError", "evalue": "An error occurred (AccessDeniedException) when calling the ListPredictors operation: User: arn:aws:sts::282494629315:assumed-role/AmazonSageMaker-ExecutionRole-20220127T153361/SageMaker is not authorized to perform: forecast:ListPredictors because no VPC endpoint policy allows the forecast:ListPredictors action", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mClientError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mforecast\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlist_predictors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_api_call\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 389\u001b[0m \"%s() only accepts keyword arguments.\" % py_operation_name)\n\u001b[1;32m 390\u001b[0m \u001b[0;31m# The \"self\" in this scope is referring to the BaseClient.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 391\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_api_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moperation_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 392\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 393\u001b[0m \u001b[0m_api_call\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpy_operation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_make_api_call\u001b[0;34m(self, operation_name, api_params)\u001b[0m\n\u001b[1;32m 717\u001b[0m \u001b[0merror_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Error\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Code\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 718\u001b[0m \u001b[0merror_class\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merror_code\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 719\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merror_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparsed_response\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moperation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 720\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 721\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mClientError\u001b[0m: An error occurred (AccessDeniedException) when calling the ListPredictors operation: User: arn:aws:sts::282494629315:assumed-role/AmazonSageMaker-ExecutionRole-20220127T153361/SageMaker is not authorized to perform: forecast:ListPredictors because no VPC endpoint policy allows the forecast:ListPredictors action" ] } ], "source": [ "forecast.list_predictors()" ] }, { "cell_type": "markdown", "id": "7eb4ad87", "metadata": {}, "source": [ "We can do a `ListDatasets` action to verify that we are able to make successful through the VPC endpoint" ] }, { "cell_type": "code", "execution_count": 29, "id": "fb98375c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Datasets': [],\n", " 'ResponseMetadata': {'RequestId': '98113a60-5d94-4b1e-abb0-67d46c771d17',\n", " 'HTTPStatusCode': 200,\n", " 'HTTPHeaders': {'date': 'Fri, 28 Jan 2022 22:38:04 GMT',\n", " 'content-type': 'application/x-amz-json-1.1',\n", " 'content-length': '15',\n", " 'connection': 'keep-alive',\n", " 'x-amzn-requestid': '98113a60-5d94-4b1e-abb0-67d46c771d17'},\n", " 'RetryAttempts': 0}}" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "forecast.list_datasets()" ] }, { "cell_type": "markdown", "id": "4dc7bcc1", "metadata": {}, "source": [ "#### Testing VPC endpoint through PrivateDNS\n", "\n", "Now we can test private DNS as well by enabling private DNS for `com.amazonaws.us-west-2.forecast` as well\n", "\n", "1. Go to VPC console page\n", "1. Click `Endpoints` on the left navigation panel\n", "1. Select the VPC endpoint we created for `com.amazonaws.us-west-2.forecast`\n", "1. Click `Actions` -> `Modify private DNS name`\n", "1. Checkmark `Enable for this endpoint`\n", "1. Click `Save changes`\n", "1. You can wait till status becomes `Available`, and you should see the private DNS name listed under `Private DNS names`, with something similar to `forecast..us-west-2.amazonaws.com`\n", "\n", "Note that the private DNS name is simliar to the public DNS name for our public endpoints at https://alpha-docs-aws.amazon.com/general/latest/gr/forecast.html#forecast_region. This means that for existing clients already calling us, if you create the VPC endpoint within the same VPC and enable private DNS, you shouldn't have to make much code change afterwards.\n", "\n", "We will test this below where we initialize the standard forecast client that points to the public DNS which resolves to the private DNS and resolves to the VPC endpoint." ] }, { "cell_type": "code", "execution_count": 30, "id": "e52e0d3c", "metadata": {}, "outputs": [], "source": [ "forecast = session.client(service_name='forecast')" ] }, { "cell_type": "code", "execution_count": 31, "id": "7de9cb07", "metadata": {}, "outputs": [ { "ename": "ClientError", "evalue": "An error occurred (AccessDeniedException) when calling the ListPredictors operation: User: arn:aws:sts::282494629315:assumed-role/AmazonSageMaker-ExecutionRole-20220127T153361/SageMaker is not authorized to perform: forecast:ListPredictors because no VPC endpoint policy allows the forecast:ListPredictors action", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mClientError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mforecast\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlist_predictors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_api_call\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 389\u001b[0m \"%s() only accepts keyword arguments.\" % py_operation_name)\n\u001b[1;32m 390\u001b[0m \u001b[0;31m# The \"self\" in this scope is referring to the BaseClient.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 391\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_api_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moperation_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 392\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 393\u001b[0m \u001b[0m_api_call\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpy_operation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_make_api_call\u001b[0;34m(self, operation_name, api_params)\u001b[0m\n\u001b[1;32m 717\u001b[0m \u001b[0merror_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Error\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Code\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 718\u001b[0m \u001b[0merror_class\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merror_code\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 719\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merror_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparsed_response\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moperation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 720\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 721\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mClientError\u001b[0m: An error occurred (AccessDeniedException) when calling the ListPredictors operation: User: arn:aws:sts::282494629315:assumed-role/AmazonSageMaker-ExecutionRole-20220127T153361/SageMaker is not authorized to perform: forecast:ListPredictors because no VPC endpoint policy allows the forecast:ListPredictors action" ] } ], "source": [ "forecast.list_predictors()" ] }, { "cell_type": "code", "execution_count": 32, "id": "d19cd3be", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Datasets': [],\n", " 'ResponseMetadata': {'RequestId': 'aa280a6a-3a45-42ef-9cad-18bc03ac3e1a',\n", " 'HTTPStatusCode': 200,\n", " 'HTTPHeaders': {'date': 'Fri, 28 Jan 2022 22:43:32 GMT',\n", " 'content-type': 'application/x-amz-json-1.1',\n", " 'content-length': '15',\n", " 'connection': 'keep-alive',\n", " 'x-amzn-requestid': 'aa280a6a-3a45-42ef-9cad-18bc03ac3e1a'},\n", " 'RetryAttempts': 0}}" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "forecast.list_datasets()" ] }, { "cell_type": "markdown", "id": "36241f76", "metadata": {}, "source": [ "#### Restoring full access policy\n", "\n", "From above, we can see that the VPCE policy is still being applied, so we learned that we are now making connections through the VPC endpoint.\n", "\n", "VPC endpoint policy can be useful since it's applied in conjunction with the calling identity's IAM permissions. For example, if you want to restrict all calls to only `ListDatasets` for all calls through the VPC endpoint, you can do so via the VPC endpoint policy instead of having to restrict each user's IAM permission. Of course, the best practice is to restrict user's IAM permission down to only what's needed though.\n", "\n", "Since we have seen how VPC endpoint policies work, let's restore the policy back to full access now for the rest of the notebook. Note that you can customize the VPC endpoint policy, and we have some example policies listed at https://docs.aws.amazon.com/forecast/latest/dg/vpc-interface-endpoints.html\n", "\n", "1. Go to VPC console page\n", "1. Click `Endpoints` on the left navigation panel\n", "1. Select the VPC endpoint we created for `com.amazonaws.us-west-2.forecast`\n", "1. Click on the `Policy` tab\n", "1. Click `Edit Policy`\n", "1. Select `Full access`\n", "1. Click `Save`\n", "1. It takes a few minutes for the policy to update. But you should be able to execute any Forecast APIs afterwards" ] }, { "cell_type": "code", "execution_count": 34, "id": "0e1fc5aa", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Predictors': [],\n", " 'ResponseMetadata': {'RequestId': '44aa99c1-c765-4a96-adfc-b487b6da578b',\n", " 'HTTPStatusCode': 200,\n", " 'HTTPHeaders': {'date': 'Fri, 28 Jan 2022 22:49:59 GMT',\n", " 'content-type': 'application/x-amz-json-1.1',\n", " 'content-length': '17',\n", " 'connection': 'keep-alive',\n", " 'x-amzn-requestid': '44aa99c1-c765-4a96-adfc-b487b6da578b'},\n", " 'RetryAttempts': 0}}" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "forecast.list_predictors()" ] }, { "cell_type": "markdown", "id": "8b3cf7b5", "metadata": {}, "source": [ "## Conclusion\n", "\n", "Through this guide, we learned how to create VPC endpoints through Amazon Forecast's integration with VPC PrivateLink, as well as how to connect to Amazon Forecast services using these VPC endpoints via [Notebook](https://github.com/aws-samples/amazon-forecast-samples/tree/main/notebooks/advanced/VPC_PrivateLink/Connect_Via_VPC_Endpoint_Guide.ipynb). We also learned what VPC endpoint policies are, and how to configure VPC endpoint policies to verify that API calls are going through the VPC endpoints. Through VPC endpoints, you can now connect to Amazon Forecast services through these endpoints without having to connect through public internet.\n", "\n", "To learn more, review [Forecast and Interface VPC endpoints](https://docs.aws.amazon.com/forecast/latest/dg/vpc-interface-endpoints.html). All these new capabilities are available in all Regions where Forecast is publicly available. For more information about Region availability, see [Amazon Forecast endpoints and quotas](https://alpha-docs-aws.amazon.com/general/latest/gr/forecast.html#forecast_region)\n" ] }, { "cell_type": "markdown", "id": "8c15730d", "metadata": {}, "source": [ "## Bonus: Walking through Forecast Creation \n", "\n", "For the rest of this notebook, we will be just revisiting the Forecast creation steps within the Forecast Quick Start Guide, just to show that the API calls are successful even inside VPC.\n", "\n", "However, if you want more explanations, please look at https://github.com/aws-samples/amazon-forecast-samples/blob/main/notebooks/basic/Getting_Started/Amazon_Forecast_Quick_Start_Guide.ipynb" ] }, { "cell_type": "markdown", "id": "31e98cc5", "metadata": {}, "source": [ "#### Creating the Dataset" ] }, { "cell_type": "code", "execution_count": 35, "id": "1b7c227a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The Dataset with ARN arn:aws:forecast:us-west-2:282494629315:dataset/TAXI_TS_PRIVATE_LINK is now ACTIVE.\n" ] } ], "source": [ "DATASET_FREQUENCY = \"H\" # H for hourly.\n", "TS_DATASET_NAME = \"TAXI_TS_PRIVATE_LINK\"\n", "TS_SCHEMA = {\n", " \"Attributes\":[\n", " {\n", " \"AttributeName\":\"timestamp\",\n", " \"AttributeType\":\"timestamp\"\n", " },\n", " {\n", " \"AttributeName\":\"item_id\",\n", " \"AttributeType\":\"string\"\n", " },\n", " {\n", " \"AttributeName\":\"target_value\",\n", " \"AttributeType\":\"integer\"\n", " }\n", " ]\n", "}\n", "\n", "create_dataset_response = forecast.create_dataset(Domain=\"CUSTOM\",\n", " DatasetType='TARGET_TIME_SERIES',\n", " DatasetName=TS_DATASET_NAME,\n", " DataFrequency=DATASET_FREQUENCY,\n", " Schema=TS_SCHEMA)\n", "\n", "ts_dataset_arn = create_dataset_response['DatasetArn']\n", "describe_dataset_response = forecast.describe_dataset(DatasetArn=ts_dataset_arn)\n", "\n", "print(f\"The Dataset with ARN {ts_dataset_arn} is now {describe_dataset_response['Status']}.\")" ] }, { "cell_type": "markdown", "id": "4e3ad83f", "metadata": {}, "source": [ "#### Importing the Dataset" ] }, { "cell_type": "code", "execution_count": 39, "id": "14ba20dc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Waiting for Dataset Import Job with ARN arn:aws:forecast:us-west-2:282494629315:dataset-import-job/TAXI_TS_PRIVATE_LINK/TAXI_TTS_IMPORT_PRIVATE_LINK to become ACTIVE. This process could take 5-10 minutes.\n", "\n", "Current Status:\n", "CREATE_PENDING .\n", "CREATE_IN_PROGRESS ....................................\n", "ACTIVE \n", "\n", "\n", "The Dataset Import Job with ARN arn:aws:forecast:us-west-2:282494629315:dataset-import-job/TAXI_TS_PRIVATE_LINK/TAXI_TTS_IMPORT_PRIVATE_LINK is now ACTIVE.\n" ] } ], "source": [ "TIMESTAMP_FORMAT = \"yyyy-MM-dd hh:mm:ss\"\n", "TS_IMPORT_JOB_NAME = \"TAXI_TTS_IMPORT_PRIVATE_LINK\"\n", "TIMEZONE = \"EST\"\n", "\n", "ts_dataset_import_job_response = \\\n", " forecast.create_dataset_import_job(DatasetImportJobName=TS_IMPORT_JOB_NAME,\n", " DatasetArn=ts_dataset_arn,\n", " DataSource= {\n", " \"S3Config\" : {\n", " \"Path\": ts_s3_path,\n", " \"RoleArn\": role_arn\n", " } \n", " },\n", " TimestampFormat=TIMESTAMP_FORMAT,\n", " TimeZone = TIMEZONE)\n", "\n", "ts_dataset_import_job_arn = ts_dataset_import_job_response['DatasetImportJobArn']\n", "describe_dataset_import_job_response = forecast.describe_dataset_import_job(DatasetImportJobArn=ts_dataset_import_job_arn)\n", "\n", "print(f\"Waiting for Dataset Import Job with ARN {ts_dataset_import_job_arn} to become ACTIVE. This process could take 5-10 minutes.\\n\\nCurrent Status:\")\n", "\n", "status = util.wait(lambda: forecast.describe_dataset_import_job(DatasetImportJobArn=ts_dataset_import_job_arn))\n", "\n", "describe_dataset_import_job_response = forecast.describe_dataset_import_job(DatasetImportJobArn=ts_dataset_import_job_arn)\n", "print(f\"\\n\\nThe Dataset Import Job with ARN {ts_dataset_import_job_arn} is now {describe_dataset_import_job_response['Status']}.\")" ] }, { "cell_type": "markdown", "id": "25f5675e", "metadata": {}, "source": [ "#### Creating a DatasetGroup" ] }, { "cell_type": "code", "execution_count": 40, "id": "7c25da5a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The DatasetGroup with ARN arn:aws:forecast:us-west-2:282494629315:dataset-group/TAXI_DEMO_PRIVATE_LINK is now ACTIVE.\n" ] } ], "source": [ "DATASET_GROUP_NAME = \"TAXI_DEMO_PRIVATE_LINK\"\n", "DATASET_ARNS = [ts_dataset_arn]\n", "\n", "create_dataset_group_response = \\\n", " forecast.create_dataset_group(Domain=\"CUSTOM\",\n", " DatasetGroupName=DATASET_GROUP_NAME,\n", " DatasetArns=DATASET_ARNS)\n", "\n", "dataset_group_arn = create_dataset_group_response['DatasetGroupArn']\n", "describe_dataset_group_response = forecast.describe_dataset_group(DatasetGroupArn=dataset_group_arn)\n", "\n", "print(f\"The DatasetGroup with ARN {dataset_group_arn} is now {describe_dataset_group_response['Status']}.\")" ] }, { "cell_type": "markdown", "id": "1f0b00d3", "metadata": {}, "source": [ "#### Train a predictor" ] }, { "cell_type": "code", "execution_count": null, "id": "63adaf5f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Waiting for Predictor with ARN arn:aws:forecast:us-west-2:282494629315:predictor/TAXI_PREDICTOR_01FTHF1KK7E6VVR676WVN24MXC to become ACTIVE. Depending on data size and predictor setting,it can take several hours to be ACTIVE.\n", "\n", "Current Status:\n", "CREATE_PENDING ..\n", "CREATE_IN_PROGRESS ..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................." ] } ], "source": [ "PREDICTOR_NAME = \"TAXI_PREDICTOR\"\n", "FORECAST_HORIZON = 24\n", "FORECAST_FREQUENCY = \"H\"\n", "HOLIDAY_DATASET = [{\n", " 'Name': 'holiday',\n", " 'Configuration': {\n", " 'CountryCode': ['US']\n", " }\n", "}]\n", "\n", "create_auto_predictor_response = \\\n", " forecast.create_auto_predictor(PredictorName = PREDICTOR_NAME,\n", " ForecastHorizon = FORECAST_HORIZON,\n", " ForecastFrequency = FORECAST_FREQUENCY,\n", " DataConfig = {\n", " 'DatasetGroupArn': dataset_group_arn, \n", " 'AdditionalDatasets': HOLIDAY_DATASET\n", " },\n", " ExplainPredictor = True)\n", "\n", "predictor_arn = create_auto_predictor_response['PredictorArn']\n", "print(f\"Waiting for Predictor with ARN {predictor_arn} to become ACTIVE. Depending on data size and predictor setting,it can take several hours to be ACTIVE.\\n\\nCurrent Status:\")\n", "\n", "status = util.wait(lambda: forecast.describe_auto_predictor(PredictorArn=predictor_arn))\n", "\n", "describe_auto_predictor_response = forecast.describe_auto_predictor(PredictorArn=predictor_arn)\n", "print(f\"\\n\\nThe Predictor with ARN {predictor_arn} is now {describe_auto_predictor_response['Status']}.\")" ] }, { "cell_type": "code", "execution_count": 46, "id": "74d3ced6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ACTIVE \n", "\n", "\n", "The Predictor with ARN arn:aws:forecast:us-west-2:282494629315:predictor/TAXI_PREDICTOR_01FTHF1KK7E6VVR676WVN24MXC is now ACTIVE.\n" ] } ], "source": [ "status = util.wait(lambda: forecast.describe_auto_predictor(PredictorArn=predictor_arn))\n", "\n", "describe_auto_predictor_response = forecast.describe_auto_predictor(PredictorArn=predictor_arn)\n", "print(f\"\\n\\nThe Predictor with ARN {predictor_arn} is now {describe_auto_predictor_response['Status']}.\")" ] }, { "cell_type": "markdown", "id": "b22c42b7", "metadata": {}, "source": [ "#### Generate forecasts" ] }, { "cell_type": "code", "execution_count": 50, "id": "7e56e8f6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Waiting for Forecast with ARN arn:aws:forecast:us-west-2:282494629315:forecast/TAXI_FORECAST_PRIVATE_LINK to become ACTIVE. Depending on data size and predictor settings,it can take several hours to be ACTIVE.\n", "\n", "Current Status:\n", "CREATE_PENDING \n", "CREATE_IN_PROGRESS ..............................................................................................\n", "ACTIVE \n", "\n", "\n", "The Forecast with ARN arn:aws:forecast:us-west-2:282494629315:forecast/TAXI_FORECAST_PRIVATE_LINK is now ACTIVE.\n" ] } ], "source": [ "FORECAST_NAME = \"TAXI_FORECAST_PRIVATE_LINK\"\n", "\n", "create_forecast_response = \\\n", " forecast.create_forecast(ForecastName=FORECAST_NAME,\n", " PredictorArn=predictor_arn)\n", "\n", "forecast_arn = create_forecast_response['ForecastArn']\n", "print(f\"Waiting for Forecast with ARN {forecast_arn} to become ACTIVE. Depending on data size and predictor settings,it can take several hours to be ACTIVE.\\n\\nCurrent Status:\")\n", "\n", "status = util.wait(lambda: forecast.describe_forecast(ForecastArn=forecast_arn))\n", "\n", "describe_forecast_response = forecast.describe_forecast(ForecastArn=forecast_arn)\n", "print(f\"\\n\\nThe Forecast with ARN {forecast_arn} is now {describe_forecast_response['Status']}.\")" ] }, { "cell_type": "markdown", "id": "4f0c1d18", "metadata": {}, "source": [ "#### Load ground truth for pick-up location 48 on February 1, 2019." ] }, { "cell_type": "code", "execution_count": 51, "id": "a7a5ef99", "metadata": {}, "outputs": [], "source": [ "ITEM_ID = \"48\"\n", "\n", "taxi_feb_df = pd.read_csv(\"data/taxi-feb2019.csv\", dtype = object, names=['timestamp','item_id','target_value'])\n", "taxi_feb_df.target_value = taxi_feb_df.target_value.astype(float)\n", "\n", "actuals = taxi_feb_df[(taxi_feb_df['item_id'] == ITEM_ID)]" ] }, { "cell_type": "markdown", "id": "12782c51", "metadata": {}, "source": [ "#### Query forecasts for pick-up location 48 on February 1, 2019." ] }, { "cell_type": "code", "execution_count": 56, "id": "2ce31334", "metadata": {}, "outputs": [], "source": [ "# Creating client that has privateDNS enabled, so still going through VPC\n", "forecastquery = session.client(service_name='forecastquery')" ] }, { "cell_type": "code", "execution_count": 57, "id": "170a455c", "metadata": {}, "outputs": [], "source": [ "forecast_response = forecastquery.query_forecast(\n", " ForecastArn=forecast_arn,\n", " Filters={\"item_id\": ITEM_ID}\n", ")" ] }, { "cell_type": "code", "execution_count": 58, "id": "6565b7e4", "metadata": {}, "outputs": [], "source": [ "\n", "forecasts_p10_df = pd.DataFrame.from_dict(forecast_response['Forecast']['Predictions']['p10'])\n", "forecasts_p50_df = pd.DataFrame.from_dict(forecast_response['Forecast']['Predictions']['p50'])\n", "forecasts_p90_df = pd.DataFrame.from_dict(forecast_response['Forecast']['Predictions']['p90'])" ] }, { "cell_type": "markdown", "id": "08bdbe1d", "metadata": {}, "source": [ "#### Compare the forecasts with ground truth" ] }, { "cell_type": "code", "execution_count": 60, "id": "be6fea71", "metadata": {}, "outputs": [], "source": [ "import dateutil" ] }, { "cell_type": "code", "execution_count": 61, "id": "1da56f4b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "results_df = pd.DataFrame(columns=['timestamp', 'value', 'source'])\n", "\n", "for index, row in actuals.iterrows():\n", " clean_timestamp = dateutil.parser.parse(row['timestamp'])\n", " results_df = results_df.append({'timestamp' : clean_timestamp , 'value' : row['target_value'], 'source': 'actual'} , ignore_index=True)\n", "for index, row in forecasts_p10_df.iterrows():\n", " clean_timestamp = dateutil.parser.parse(row['Timestamp'])\n", " results_df = results_df.append({'timestamp' : clean_timestamp , 'value' : row['Value'], 'source': 'p10'} , ignore_index=True)\n", "for index, row in forecasts_p50_df.iterrows():\n", " clean_timestamp = dateutil.parser.parse(row['Timestamp'])\n", " results_df = results_df.append({'timestamp' : clean_timestamp , 'value' : row['Value'], 'source': 'p50'} , ignore_index=True)\n", "for index, row in forecasts_p90_df.iterrows():\n", " clean_timestamp = dateutil.parser.parse(row['Timestamp'])\n", " results_df = results_df.append({'timestamp' : clean_timestamp , 'value' : row['Value'], 'source': 'p90'} , ignore_index=True)\n", "\n", "pivot_df = results_df.pivot(columns='source', values='value', index=\"timestamp\")\n", "\n", "pivot_df.plot(figsize=(15, 7))" ] }, { "cell_type": "markdown", "id": "b1c13929", "metadata": {}, "source": [ "* **Impact scores** measure the relative impact attributes have on forecast values. For example, if the holiday attribute has an impact score that is twice as large as another possible attribute, say weather, you can conclude that the holiday has twice the impact on forecast values than the weather. \n", "* **Impact scores** also provide information on whether an attribute increases or decreases the forecasted value. A negative impact scores reflects that the attribute tends to decrease the value of the forecast." ] }, { "cell_type": "markdown", "id": "5ab8e605", "metadata": {}, "source": [ "## Clean-up \n", "Uncomment the code section to delete all resources that were created in this notebook." ] }, { "cell_type": "code", "execution_count": 62, "id": "d8437459", "metadata": {}, "outputs": [], "source": [ "# forecast.delete_resource_tree(ResourceArn = dataset_group_arn)\n", "# forecast.delete_resource_tree(ResourceArn = ts_dataset_arn)" ] }, { "cell_type": "markdown", "id": "de1f0f35", "metadata": {}, "source": [ "Be sure to also manually delete the following resources that we created\n", "\n", "- VPC endpoints\n", "- Notebook instance\n", "- Notebook instance role\n", "- VPC\n", "- Subnet\n", "- Security Group\n" ] } ], "metadata": { "kernelspec": { "display_name": "conda_python3", "language": "python", "name": "conda_python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.13" } }, "nbformat": 4, "nbformat_minor": 5 }