-
Notifications
You must be signed in to change notification settings - Fork 2
/
skill.ts
78 lines (72 loc) · 3.45 KB
/
skill.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import { PolicyStatement } from '@aws-cdk/aws-iam';
import { CfnPermission } from '@aws-cdk/aws-lambda';
import { Bucket } from '@aws-cdk/aws-s3';
import { CfnFunction, CfnFunctionProps, CfnSimpleTable } from '@aws-cdk/aws-serverless';
import { App, DeletionPolicy, Fn, Output, ScopedAws, Secret, Stack } from '@aws-cdk/cdk';
export interface AlexaSkillConfig {
skillId : string;
skillName : string;
thundraKey? : string;
environment? : { [key : string] : string };
userAttribute? : string;
}
export class AlexaSkillStack extends Stack {
constructor(parent : App, config : AlexaSkillConfig) {
super(parent, config.skillName);
this.templateOptions.description = `The Alexa Skill ${config.skillName}`;
const aws = new ScopedAws(this);
const assetBucket = new Bucket(this, 'AssetBucket', {
bucketName: `${aws.accountId}-${config.skillName}-${aws.region}-assets`,
});
assetBucket.grantPublicAccess();
const userTable = new CfnSimpleTable(this, 'AttributesTable', {
primaryKey: {
name: config.userAttribute || 'id',
type: 'String',
},
});
const functionConfig : CfnFunctionProps = {
handler: 'bundle.handler',
runtime: 'nodejs8.10',
timeout: 10,
autoPublishAlias: 'latest',
codeUri: './skill/dist/bundle.js',
policies: [
{
statement: new PolicyStatement()
.addActions('dynamodb:Batch*', 'dynamodb:DeleteItem', 'dynamodb:Get*', 'dynamodb:PutItem', 'dynamodb:UpdateItem', 'dynamodb:Query', 'dynamodb:Scan')
// tslint:disable-next-line:no-invalid-template-strings
.addResource(Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${AttributesTable}')),
},
],
environment: {
variables: {
...config.environment,
TABLE_NAME: userTable.ref,
ASSET_BUCKET: assetBucket.bucketName,
ASSET_BUCKET_URL: assetBucket.bucketUrl,
SKILL_ID: config.skillId,
},
},
};
if (config.thundraKey) {
functionConfig.runtime = 'provided';
functionConfig.layers = [`arn:aws:lambda:${aws.region}:269863060030:layer:thundra-lambda-node-layer:7`];
((functionConfig.environment as CfnFunction.FunctionEnvironmentProperty)
.variables as { [key : string] : string }).thundra_apiKey = config.thundraKey;
}
const skillFunction = new CfnFunction(this, 'SkillFunction', functionConfig);
const skillFunctionPermission = new CfnPermission(this, 'SkillFunctionPermission', {
action: 'lambda:invokeFunction',
// tslint:disable-next-line:no-invalid-template-strings
functionName: Fn.sub('${SkillFunction.Version}'),
principal: 'alexa-appkit.amazon.com',
});
skillFunctionPermission.options.deletionPolicy = DeletionPolicy.Retain;
skillFunctionPermission.options.updateReplacePolicy = DeletionPolicy.Retain;
const deployOutput = new Output(this, 'overrides', {
// tslint:disable-next-line:no-invalid-template-strings
value: Fn.sub('{"manifest": {"apis": {"custom": {"endpoint": {"uri": "${SkillFunction.Version}"}}}}}'),
});
}
}