Use Personal AWS Resources with Your Alexa-hosted Skill

When you create an Alexa-hosted skill, Alexa stores your code and resources on AWS for you. For details about hosted skills, see Build a Skill End-to-end Using an Alexa-hosted Skill.

When you create an Alexa-hosted skill, you get access to three AWS Lambda endpoints, an Amazon S3 bucket for media storage, and an Amazon DynamoDB table for persisting data to DynamoDB. If your skill requires additional AWS services, or if your usage exceeds the usage limits, you can provision the additional resources in your own AWS account.

With the AWS Lambda execution role ARN, you can seamlessly use resources on a personal AWS account to expand the functionality of your Alexa-hosted skill.

Set up permissions

To enable your Alexa-hosted skill to use resources in your personal AWS account, modify an AWS IAM role to allow access to the resource that you want your Alexa-hosted skill to access.

To get your Alexa skill ARN

  1. Open the Alexa developer console and log in.
  2. In the console, open your Alexa-hosted skill.
  3. In the code editor, click the icon for Link your personal AWS resources.
  4. Copy the ARN.

To modify an AWS IAM role

  1. Open the AWS management console and log in.
  2. In the console, open the Identity and Access Management (IAM) dashboard dashboard.
  3. In the IAM dashboard, click Roles.
  4. Click the name of the role you want to edit, and then click the Trust relationships tab.
  5. Click Edit trust relationship.
  6. Add an entry for the AWS Lambda Role Execution ARN from your Alexa-hosted skill to the Statement property and include the sts:AssumeRole action as shown in the following example. Do not overwrite other existing entries.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          Other entries here
        },
        {
          "Effect": "Allow",
          "Principal": {"AWS": "<Replace with AWS Lambda Execution Role ARN from Alexa-hosted skill>"},
          "Action": "sts:AssumeRole"
        }
      ]
    }
    

Use personal AWS resources with Node.js

In the code for your Alexa-hosted skill, assume the role using the AWS Security Token Service (STS) API. For example, the following code requests temporary credentials of a role with AWS DynamoDB access, and scans the DynamoDB table.

Copied to clipboard.


const AWS = require(aws-sdk);

const ShowUserMessageHandler = {
    //... Your canHandle function for intent ...

    async handle(handlerInput) {
        // 1. Assume the AWS resource role using STS AssumeRole Action
        const STS = new AWS.STS({ apiVersion: '2011-06-15' });
        const credentials = await STS.assumeRole({
            RoleArn: '<Your AWS resource role ARN>',
            RoleSessionName: 'ExampleSkillRoleSession' // You can rename with any name
        }, (err, res) => {
            if (err) {
                console.log('AssumeRole FAILED: ', err);
                throw new Error('Error while assuming role');
            }
            return res;
        }).promise();

        // 2. Make a new DynamoDB instance with the assumed role credentials
        //    and scan the DynamoDB table
        const dynamoDB = new AWS.DynamoDB({
            apiVersion: '2012-08-10',
            accessKeyId: credentials.Credentials.AccessKeyId,
            secretAccessKey: credentials.Credentials.SecretAccessKey,
            sessionToken: credentials.Credentials.SessionToken
        });
        const tableData = await dynamoDB.scan({ TableName: 'TestTable' }, (err, data) => {
            if (err) {
                console.log('Scan FAILED', err);
                throw new Error('Error while scanning table');
            }
            return data;
        }).promise();

        // ... Use table data as required ...
    }
};

Use personal AWS resources with Python

In the code for your Alexa-hosted skill, assume the role using the AWS Security Token Service (STS) API. For example, the following code requests temporary credentials of a role with AWS DynamoDB access, and then it scans the DynamoDB table.

Copied to clipboard.

import boto3

def handle(self, handler_input):
    # type: (HandlerInput) -> Response

    # 1. Assume the AWS resource role using STS AssumeRole Action
    sts_client = boto3.client('sts')
    assumed_role_object=sts_client.assume_role(RoleArn="<Your AWS resource role ARN>", RoleSessionName="AssumeRoleSession1")
    credentials=assumed_role_object['Credentials']

    # 2. Make a new DynamoDB instance with the assumed role credentials
    dynamodb = boto3.resource('dynamodb',
                      aws_access_key_id=credentials['AccessKeyId'],
                      aws_secret_access_key=credentials['SecretAccessKey'],
                      aws_session_token=credentials['SessionToken'],
                      region_name='us-east-1')

    # 3. Perform DynamoDB operations on the table
    try:
        table = dynamodb.Table('TestTable')
        response = table.scan()
        # Use the response as required . .
    except ResourceNotExistsError:
        # Exception handling
        raise
    except Exception as e:
        # Exception handling
        raise e
    # continue . .
    return (
        handler_input.response_builder.response
    )