This repository has two purposes:
- Educate about the use of AWS CloudFormation (Cfn) as part of ASK CLI's cfn-deployer, and
- Offer examples for a range of common Cfn use cases. Currently, there include:
- The ASK CLI's default 'Hello world' skill, to illustrate how cfn-deployer works on a basic level
- An improved 'basic' skill (using only Lambda and CloudWatch resources) that features some useful cfn-deployer tips
- A 'DynamoDB' skill as an example for a DynamoDB resource and Cfn conditional statements
- A 'content delivery' skill as an example for an S3 bucket and a CloudFront CDN, and string manipulation
- A 'monitoring' skill as an example for a Cloudwatch Alarm and an SNS topic, and how to use custom project parameters
- A Flash Briefing skill as an example for an API Gateway, and how to set up a different skill type than 'custom'
- An 'Aurora' skill as an example for persistence using an Aurora Serverless DB, its Data API and the AWS Secret required for authentication
- An ASK CLI-less skill as an example for how to deploy a skill using Cfn's
Alexa::ASK::Skill
resource type, and for how to use Cfn metadata to structure and annotate parameter input
This README provides a general introduction to Cfn, as far as relevant for Alexa skill development, and outlines the interaction between ASK CLI and Cfn.
Prerequisite for trying out these examples is a configured ASK CLI profile that is associated with a configured AWS CLI profile. The AWS CLI user needs to have a the IAM policies required for deploying the respective resources (e.g. lambda:CreateFunction
).
A convenient set of managed IAM policies is provided for each project. Generally, what you'll need for each project, and corresponding managed IAM policies are:
- CloudFormation permissions -->
AWSCloudFormationFullAccess
- Lambda permissions to set up the Lambda function -->
AWSLambda_FullAccess
- CloudWatch permissions to set up the CloudWatch log group -->
AWSLambda_FullAccess
- IAM permissions to create the Lambda role and policy -->
CloudWatchFullAccess
In some cases you might want to try out some of the templates in this guide without setting up a skill project (or an ASK CLI profile) first. This is possible, e.g. if you just upload one of the templates files in the AWS Cfn Console. One issue you'll encounter is to provide values for the parameters CodeBucket
, CodeKey
, CodeVersion
& SkillId
(explained in the 'Interaction b/w Cfn and ASK CLI' section below). If you fill in nonsense values (at least for the Code*
parameters), the deployment will fail!
Instead, you can use these 'dummy' values:
- CodeBucket:
cfn-source-eu-west-1
- CodeKey:
cfnGuideDummy.zip
- CodeVersion:
CpDMWFsA1rhwyso8BRArT4NBhvw7rZTw
- SkillId:
amzn1.ask.skill.20998b0d-c197-4289-8e31-44f2adb51240
To get started with any of the example skills:
- Navigate into the respective directory (e.g.
./basicSkill
). - Check out
README.md
to learn what's particular about this example, and whether it requires specific configuration. - One mandatory step if you use a non-default ASK CLI profile is to open
ask-resources.json
and replace the property keyprofiles.default
with your profile name, e.g.profiles.my-custom-profile
. - Deploy the skill project using
ask deploy [--profile my-custom-profile]
. The terminal will display the progress, and once ot's done you can test the skill in the Alexa Developer Console and inspect the stack in the AWS Cfn console.
From the AWS Cfn Documentation (emphasis mine):
AWS CloudFormation is a service that helps you model and set up your AWS resources so that you can spend less time managing those resources and more time focusing on your applications that run in AWS. You create a template that describes all the AWS resources that you want (like Amazon EC2 instances or Amazon RDS DB instances), and CloudFormation takes care of provisioning and configuring those resources for you. You don't need to individually create and configure AWS resources and figure out what's dependent on what; CloudFormation handles that.
Cfn is AWS' 'infrastructure as code' solution, i.e. it allows provisioning and managing cloud resources by writing a template file that is both human readable, and machine consumable. This has at least three main benefits when compared to setting up infrastructure 'by hand':
- Iterating on finding the right set of configuration is less messy.
- Infrastructure with all (or most) of its components and their configurations become part of the project's codebase, and can be managed using version control etc.
- It becomes easier to share models of infrastructure, both with partners and with the (developer) community.
A Cfn template is a YAML (or JSON, but YAML is generally preferred) file that lists all of the logical resources for a project, along with their configuration and optionally parameters. Once a template is deployed with Cfn, it creates a stack that contains all the provisioned physical resources, and optional output values.
In the most generalized terms (in the context of Alexa skill development), Cfn templates have the following sections
AWSTemplateFormatVersion
: Mandatory, is always2010-09-09
- Parameters: Parameters provide degrees of freedom during the creation stage of a Cfn stack:
- Parameters always have a name, which needs to be unique within a template and by which it can be referenced
- Parameters can have a
Type
ofString
orNumber
- Parameters can have a
Default
value. If they don't, user input is required during cration- ASK CLI Cfn templates have some parameters without defaults (
SkillId
,CodeBucket
,CodeKey
andCodeVersion
, see section "placeholder" below)
- ASK CLI Cfn templates have some parameters without defaults (
- Parameters can have constraints, depending on their type:
String
parameters can have anMinLength
,MaxLength
,AllowedPattern
orAllowedValues
Number
parameters can have aMinValue
,MaxValue
orAllowedValues
- Resources: Resources are instances of AWS services, e.g. Lambda functions and permission, IAM policies and roles, Cloudwatch log groups etc.
- Logical resources provide the definition and configuration of resources within a Cfn template. Logical resource names need to be unique within a template.
- Physical resources are AWS resources that have been provisioned as part of an AWS Cfn stack. Logical resources typically have an ARN that is universally unique, and may incur costs.
- Resources always have a
Type
, e.g.AWS::Lambda::Function
for a Lambda function. A list of all AWs resource types can be fund here. - Resources always have
Properties
, but the individual propoerty keys are specific for each resource type. As an example, the properties of a Lambda function are described here in detail.
- Outputs: Outputs are variables that are declared in the Cfn template, and whose values are assigned per stack deployment.
- In the context of the ASK CLI, only one output variable is used:
SkillEndpoint
, whose value populates themanifest.apis.custom.endpoint.uri
attribute of the skill's manifest (skill-package/skill.json
)
- In the context of the ASK CLI, only one output variable is used:
- Description: Each parameter, resource or output as well as the template itself can have a description.
- Other: Cfn templates can also have rules, mappings, conditions and transformers (macros), but they are mostly not in scope for this repo.
@ask-cli/cfn-deployer
is the so-called deploy delegate of ASK CLI, and is therefore neatly integrated.
If you choose to use cfn-deployer
when creating a new skill, there will be a path infrastrucutre/cfn-deployer/
in the skill project's root directory, containing only the Cfn template skill-stack.yaml
.
The cfn-deployer
can be configured using the profiles.<default>.skillInfrastructure
property of the ask-resources.json
file in the root directory. The 'basic' skill in this repo will go more into the details, but at this point we consider only these sub-propoerties:
userConfig.runtime
: Will be used to configure the Lambda function. Default value isnodejs12.x
userConfig.handler
: Will be used to configure the Lambda function. Default value isindex.handler
userConfig.templatePath
: Default is./infrastructure/cfn-deployer/skill-stack.yaml
userConfig.awsRegion
: Uses the configured AWS region for your default AWS profile, e.g.eu-west-1
In your first ask deploy
deployment, the following things will happen:
- ASK CLI creates the skill itself, based on the skill manifest and language model in the
skill-package
folder. - ASK CLI creates a folder
.ask
in which it will save deployment data, such as the ID of the skill from step 1. - ASK CLI bundles the code from the
lambda
folder in the.ask/lambda
folder. - ASK CLI creates an AWS S3 bucket, uploads the bundled
lambda
code there, and saves the bucket name, key and version in.ask/ask-states.json
. - ASK CLI passes the parameters
CodeBucket
,CodeKey
,CodeVersion
&SkillId
from.ask/ask-states.json
, andLambdaRuntime
&LambdaHandler
from.ask-resources.json
into the Cfn deploy process, using the template frominfrastrucutre/cfn-deployer/skill-stack.yaml
. - Once the infrastructure is deployed, ASK CLI takes the output parameter
SkillEndpoint
and saves it in.ask/ask-states.json
. - ASK CLI updates the skill manifest in
skill-package/skill.json
with the skill endpoint