'Is there a way to deploy a Lex bot using CDK?
I want to deploy a Lex bot to my AWS account using CDK.
Looking at the API reference documentation I can't find a construct for Lex. Also, I found this issue on the CDK GitHub repository which confirms there is no CDK construct for Lex.
Is there any workaround to deploy the Lex bot or another tool for doing this ?
Solution 1:[1]
Edit: CloudFormation support for AWS Lex is now available, see Wesley Cheek's answer. Below is my original answer which solved the lack of CloudFormation support using custom resources.
There is! While perhaps a bit cumbersome, it's totally possible using custom resources.
Custom resources work by defining a lambda that handles creation and deletion events for the custom resource. Since it's possible to create and delete AWS Lex bots using the AWS API, we can make the lambda do this when the resource gets created or destroyed.
Here's a quick example I wrote in TS/JS:
CDK Code (TypeScript):
import * as path from 'path';
import * as cdk from '@aws-cdk/core';
import * as iam from '@aws-cdk/aws-iam';
import * as logs from '@aws-cdk/aws-logs';
import * as lambda from '@aws-cdk/aws-lambda';
import * as cr from '@aws-cdk/custom-resources';
export class CustomResourceExample extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Lambda that will handle the different cloudformation resource events
const lexBotResourceHandler = new lambda.Function(this, 'LexBotResourceHandler', {
code: lambda.Code.fromAsset(path.join(__dirname, 'lambdas')),
handler: 'lexBotResourceHandler.handler',
runtime: lambda.Runtime.NODEJS_14_X,
});
lexBotResourceHandler.addToRolePolicy(new iam.PolicyStatement({
resources: ['*'],
actions: ['lex:PutBot', 'lex:DeleteBot']
}))
// Custom resource provider, specifies how the custom resources should be created
const lexBotResourceProvider = new cr.Provider(this, 'LexBotResourceProvider', {
onEventHandler: lexBotResourceHandler,
logRetention: logs.RetentionDays.ONE_DAY // Default is to keep forever
});
// The custom resource, creating one of these will invoke the handler and create the bot
new cdk.CustomResource(this, 'ExampleLexBot', {
serviceToken: lexBotResourceProvider.serviceToken,
// These options will be passed down to the lambda
properties: {
locale: 'en-US',
childDirected: false
}
})
}
}
Lambda Code (JavaScript):
const AWS = require('aws-sdk');
const Lex = new AWS.LexModelBuildingService();
const onCreate = async (event) => {
await Lex.putBot({
name: event.LogicalResourceId,
locale: event.ResourceProperties.locale,
childDirected: Boolean(event.ResourceProperties.childDirected)
}).promise();
};
const onUpdate = async (event) => {
// TODO: Not implemented
};
const onDelete = async (event) => {
await Lex.deleteBot({
name: event.LogicalResourceId
}).promise();
};
exports.handler = async (event) => {
switch (event.RequestType) {
case 'Create':
await onCreate(event);
break;
case 'Update':
await onUpdate(event);
break;
case 'Delete':
await onDelete(event);
break;
}
};
I admit it's a very bare-bones example but hopefully it's enough to get you or anyone reading started and see how it could be built upon by adding more options and more custom resources (for example for intentions).
Solution 2:[2]
Deploying Lex using CloudFormation is now possible.
CDK support has also been added but it's only available as an L1 construct, meaning the CDK code is basically going to look like CloudFormation.
Also, since this feature just came out, some features may be missing or buggy. I have been unable to find a way to do channel integrations, and have had some problems with using image response cards, but otherwise have successfully deployed a bot and connected it with Lambda/S3 using CDK.
Solution 3:[3]
I know this is not actually answering the question as the flavour of the operating system is different here.
This was done on Debian with LXDE desktop. I wrote an automated setup script for my software, copying some snippet from that here.
Note sure if you have the same scenario.
Step 1 Disable the LXDE desktop:
I had commented out lxpanel and xscreensaver both from the default autostart and user autostart
#DISABLE THE DESKTOP
sudo sed -i 's/^@lxpanel/#@lxpanel/g' /etc/xdg/lxsession/LXDE/autostart
sudo sed -i 's/^@xscreensaver/#@xscreensaver/g' /etc/xdg/lxsession/LXDE/autostart
#DISABLE THE DESKTOP FOR THE USER
sudo sed -i 's/^@lxpanel/#@lxpanel/g' /etc/xdg/lxsession/LXDE-${user_name}/autostart
sudo sed -i 's/^@xscreensaver/#@xscreensaver/g' /etc/xdg/lxsession/LXDE-${user_name}/autostart
Step 2 Setup the application:
Note: I was using python3.7
#SETUP PYTHON VENV
python3 -m venv ${application_root_dir}/venv
cd ${application_root_dir}/venv
source ${application_root_dir}/venv/bin/activate
# Install external dependencies, if any
pip3 install <dependecny_name>
# Install your software
pip3 install <software>
deactivate
Step 3 Prepare for Atuostart (optional):
Create Script to be executed in autostart. Note this is optional, you can directly use your command in the auto start (step 4).
tee -a ${application_root_dir}/start_my_app.sh > /dev/null << EOT
#!/bin/bash
cd ${application_root_dir}
source venv/bin/activate
python3 -m package.MyApp
deactivate
EOT
# Set execute permissions
sudo chmod 744 ${root_dir}/start_my_app.sh
Step 4 Steup Atuostart:
Note: you can execute any command by setting
ExecStartin[service]
4.1 Create a new service
# CREATE A SERVICE FILE
sudo tee -a /etc/systemd/system/my_app.service > /dev/null << EOT
[Unit]
Description=Start MY_APPLICATION
After=default.target
Wants=default.target
[Service]
User=${user_name}
Group=$user_group
Environment=DISPLAY=:0.0
Environment=XAUTORITY=/home/${user_name}/.Xauthority
ExecStart=/bin/bash -c "${root_dir}/start_my_app.sh"
[Install]
WantedBy=default.target
EOT
4.2 Register and enable the service
sudo /usr/bin/systemctl daemon-reload
sudo /usr/bin/systemctl enable my_app.service
4.3 Reboot
sudo reboot
Note: To enable the desktop back for troubleshooting (if at all required - I never needed though, as ssh was enabled in my case so I was using terminal). Uncomment the commented part of lxde deskop and reboot.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Wesley Cheek |
| Solution 3 | Meritor |
