aws-lex-web-ui
aws-lex-web-ui copied to clipboard
CloudFormation Stack stuck at CREATE_IN_PROGRESS
I am trying to deploy the project using my own bootstrap S3 bucket. I have followed below process for the same:
- Create your own S3 bucket
- Modify the variables in the local build environment file:
config/env.mk
.-
BOOTSTRAP_BUCKET_PATH
-
- Upload the files to my S3 bucket using make upload from the build directory under the root of the repo.
- Deploy the stack by using the
master.yml
template. Change the theBootstrapBucket
andBootstrapPrefix
parameters to point to my own bucket and path
However, when I create a stack using CloudFormation
, only the Cognito identity pool
is deployed successfully and the process gets stuck at event CodeBuildStarter
and eventually S3Cleanup
fails with reason
Custom Resource failed to stabilize in expected time
The CloudWatch logs show an error
Unable to import module 'codebuild-start': No module named codebuild-start
Can you please help in this issue?
I assume you have your own bot created in lex ready to go as creating the default OrderFlows bot would normally be the first nested stack run by the master.yml template. It sounds like the make upload is not completing all the work required. I've been running the available shell scripts in the build directory manually and have been having success using these to create my bootstrap bucket. You might try the following in a shell assuming your are on a mac or linux system
cd build export BUCKET=<YOUR_S3_BUCKET_NAME> ./release.sh ./upload-bootstrap.sh
The release.sh will perform a full build and then upload-bootstrap.sh will upload the artifacts to YOUR_S3_BUCKET_NAME/artifacts location.
Then you can try running cloudformation again using the master.yml with a new stack in either the us-east-1 or us-west-2 regions. You would adjust the BootstrapBucket to be your bucket name and the BootstrapPrefix to be artifacts.
If this works then perhaps compare the artifacts from make upload against the artifacts from the upload-bootstrap.sh. Something I would suspect will be different. Let me know if this helps. If not let me know what your local build environment looks like (Windows/Mac/Linux and - version) and I can try replicating your setup.
Thank you @bobpskier , tried your solution but still getting the same error.
The event for Custom::CodeBuildStarter
is stuck as shown in below screenshot.
The CloudWatch
logs still show the same error:
Unable to import module 'codebuild-start': No module named codebuild-start
My codebuild-deploy.yaml
template is as follows:
AWSTemplateFormatVersion: 2010-09-09
Description: >
This template creates a CodeBuild project used to configure and deploy
the chatbot UI
Parameters:
CodeBuildName:
Type: String
Description: CodeBuild project used to configure and deploy the Lex Web UI
Default: lex-web-ui-conf-deploy
MinLength: 2
MaxLength: 255
AllowedPattern: '^[A-Za-z0-9][A-Za-z0-9\-_]{1,254}$'
ConstraintDescription: >
Should start with Alphanumeric. May contain alphanumeric, undescore
and dash.
SourceBucket:
Description: S3 bucket where the source is located
Type: String
Default: bizamica
SourceObject:
Description: S3 object zip file containing the project source
Type: String
Default: artifacts/aws-lex-web-ui/artifacts/src.zip
CustomResourceCodeObject:
Type: String
Description: >
S3 object zip file containing Lambda custom resource functions
Default: artifacts/aws-lex-web-ui/artifacts/custom-resources.zip
CleanupBuckets:
Type: String
Default: true
AllowedValues:
- true
- false
Description: >
If set to True, buckets and their associated data will be deleted on
CloudFormation stack delete. If set to False, S3 buckets will be retained.
CognitoIdentityPoolId:
Type: String
Description: >
Cognito Identity Pool Id to used in the web app configuration.
MinLength: 1
MaxLength: 55
AllowedPattern: '^[\w-]+:[0-9a-f-]+$'
ConstraintDescription: >
Alphanumeric followed by a colum and ending with a hex uuid type.
BotName:
Description: >
Name of Lex bot to be used in the web app configuration.
Type: String
MinLength: 2
MaxLength: 50
AllowedPattern: '^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_)'
ConstraintDescription: >
Must conform with the permitted Lex Bot name pattern.
ParentOrigin:
Type: String
Description: >
Browser origin (e.g. http://mysite.example.com:8080) of an
existing site that is allowed to send/receive data and events
from the web ui in an iframe setup. This is an optional
parameter. If left empty, an S3 bucket will be created to
host a sample parent site embedding the webapp as an iframe.
AllowedPattern: '(^$|^https?://[\w\.-]+(:\d+)?$)'
ConstraintDescription: Empty or valid browser origin
WebAppConfBotInitialText:
Type: String
Default: >
You can ask me for help ordering flowers. Just type "Buy
flowers" or click on the mic and say it.
Description: First bot message displayed in the chatbot UI
WebAppConfBotInitialSpeech:
Type: String
Default: Say 'Buy Flowers' to get started.
Description: >
Message spoken by bot when the microphone is first pressed
in a conversation
WebAppConfToolbarTitle:
Type: String
Default: Order Flowers
Description: Title displayed in the chatbot UI toobar
Conditions:
NeedsParentOrigin: !Equals [!Ref ParentOrigin, '']
ShouldCleanupBuckets: !Equals [!Ref CleanupBuckets, true]
Resources:
# Bucket where the web app is deployed
WebAppBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
WebsiteConfiguration:
IndexDocument: index.html
VersioningConfiguration:
Status: Enabled
CorsConfiguration:
!If
- NeedsParentOrigin
- !Ref AWS::NoValue
- CorsRules:
- AllowedMethods:
- GET
AllowedOrigins:
- !Ref ParentOrigin
CodeBuild:
Type: AWS::CodeBuild::Project
Properties:
Name: !Ref CodeBuildName
Description: Used to configure and deploy the Lex Web UI
Artifacts:
Type: NO_ARTIFACTS
Environment:
Type: LINUX_CONTAINER
Image: aws/codebuild/nodejs:8.11.0
ComputeType: BUILD_GENERAL1_SMALL
EnvironmentVariables:
- Name: BUILD_TYPE
Value: dist
- Name: POOL_ID
Value: !Ref CognitoIdentityPoolId
- Name: WEBAPP_BUCKET
Value: !Ref WebAppBucket
- Name: AWS_DEFAULT_REGION
Value: !Sub "${AWS::Region}"
- Name: BOT_NAME
Value: !Ref BotName
- Name: BOT_INITIAL_TEXT
Value: !Ref WebAppConfBotInitialText
- Name: BOT_INITIAL_SPEECH
Value: !Ref WebAppConfBotInitialSpeech
- Name: UI_TOOLBAR_TITLE
Value: !Ref WebAppConfToolbarTitle
- Name: PARENT_ORIGIN
Value: !If
- NeedsParentOrigin
- !Sub "https://${WebAppBucket.DomainName}"
- !Ref ParentOrigin
- Name: IFRAME_ORIGIN
Value: !Sub "https://${WebAppBucket.DomainName}"
ServiceRole: !GetAtt CodeBuildRole.Arn
TimeoutInMinutes: 10
Source:
Type: S3
Location: !Sub "${SourceBucket}/${SourceObject}"
BuildSpec: !Sub |
version: 0.1
phases:
pre_build:
commands:
- aws configure set region "$AWS_DEFAULT_REGION"
- make config
post_build:
commands:
- make sync-website
# custom resource to start code build project
CodeBuildStarter:
Type: Custom::CodeBuildStarter
Properties:
ServiceToken: !GetAtt CodeBuildStarterLambda.Arn
ProjectName: !Ref CodeBuild
# Lambda function for custom resource
CodeBuildStarterLambda:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref SourceBucket
S3Key: !Ref CustomResourceCodeObject
Handler: codebuild-start.handler
Role: !GetAtt CodeBuildStarterLambdaRole.Arn
Runtime: python2.7
Timeout: 120
CodeBuildRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Principal:
Service:
- codebuild.amazonaws.com
Effect: Allow
Action:
- sts:AssumeRole
Policies:
- PolicyName: S3GetObject
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:GetObject*
Resource:
- !Sub "arn:aws:s3:::${SourceBucket}/${SourceObject}"
- PolicyName: S3ReadWrite
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:Get*
- s3:Head*
- s3:List*
- s3:CreateMultipartUpload
- s3:CompleteMultipartUpload
- s3:AbortMultipartUpload
- s3:CopyObject
- s3:PutObject*
- s3:DeleteObject*
- s3:Upload*
Resource:
- !Sub "arn:aws:s3:::${WebAppBucket}"
- !Sub "arn:aws:s3:::${WebAppBucket}/*"
- PolicyName: CloudWatchLogsCodeBuild
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}"
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}:*"
CodeBuildStarterLambdaRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Principal:
Service:
- lambda.amazonaws.com
Effect: Allow
Action:
- sts:AssumeRole
Policies:
- PolicyName: LogsForLambda
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*"
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*"
- PolicyName: CodeBuildStart
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- codebuild:StartBuild
Resource: !GetAtt CodeBuild.Arn
# custom resource to cleanup S3 buckets
S3Cleanup:
Type: Custom::S3Cleanup
Condition: ShouldCleanupBuckets
Properties:
ServiceToken: !GetAtt S3CleanupLambda.Arn
Buckets:
- !Ref WebAppBucket
# Lambda function for custom resource
S3CleanupLambda:
Type: AWS::Lambda::Function
Condition: ShouldCleanupBuckets
Properties:
Code:
S3Bucket: !Ref SourceBucket
S3Key: !Ref CustomResourceCodeObject
Handler: s3-cleanup.handler
Role: !GetAtt S3CleanupLambdaRole.Arn
Runtime: python2.7
Timeout: 120
S3CleanupLambdaRole:
Type: AWS::IAM::Role
Condition: ShouldCleanupBuckets
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Principal:
Service:
- lambda.amazonaws.com
Effect: Allow
Action:
- sts:AssumeRole
Policies:
- PolicyName: LogsForLambda
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*"
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*"
- PolicyName: S3All
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:*
Resource:
- !Sub "arn:aws:s3:::${WebAppBucket}"
- !Sub "arn:aws:s3:::${WebAppBucket}/*"
Outputs:
CodeBuildProject:
Description: CodeBuild project name
Value: !Ref CodeBuild
WebAppUrl:
Value: !Sub "https://${WebAppBucket.DomainName}/index.html"
Description: URL of the web application
ParentPageUrl:
Value: !Sub "https://${WebAppBucket.DomainName}/parent.html"
Description: URL of the sample parent page
LoaderScriptUrl:
Value: !Sub "https://${WebAppBucket.DomainName}/lex-web-ui-loader.min.js"
Description: URL of the loader script
SnippetUrl:
Value: !Sub "https://${WebAppBucket.DomainName}/iframe-snippet.html"
Description: URL of a page showing the snippet to load the chatbot UI as an iframe
I am using Cygwin
on Windows10
to build this project.
The artifacts uploaded in both cases are identical except the BOOTSTRAP_BUCKET_PATH
. And I can see the custom lambda function codebuild-start.py
in the zip file custom-resporces.zip
. My S3
bucket has full public access (access provided to check if its a permission issue). Still the CodeBuild
is not able to access it. Does this have to do with any access/permissions/roles/policy related issue?
What permissions is your AWS user setup with? It is possible permissions are related however I've not seen any evidence of this yet but lets check out the Lambda function the cloud formation template is trying to execute. If I'm reading your screenshot correctly, the cloud formation template has just finished creating the CodeBuildStarterLambda function and is now trying to execute this function. Using the Lambda console please verify that the new function does exist and looks correct. You should see something like:
Next checkout the cloudwatch logs for this function:
/aws/lambda/[YOURSTACKNAME]-CodeBuildDeplo-CodeBuildStarterLambda-NNNNNNNNNNNN
From appearances this function is encountering an error and is not terminating gracefully. See if this log indicates any failure. You might see a permission or some other exception logged here.
@bobpskier I am using an admin account.
Verified in the lambda console, I am able to see the custom function.
The CloudWatch
logs for this function show the same following error with 2 more retries. Nothing related to permissions / any other exception logged there:
Unable to import module 'codebuild-start': No module named codebuild-start
I'm wondering if Cygwin is packaging up the zip for deployment in some weird way. The error seems to indicate that Lambda can't find the file codebuild-start.py. Your screen shot seems to indicate that codebuild-start.py does exist. The codebuild-deploy.yaml looks good as well. However the error seems to indicate some sort of issue in this area. Have you tried testing/editing/renaming the function directly in Lambda? Maybe make a duplicate of the function, delete the original, and rename back to code build-start.py via the inline code editing in Lambda? Also I've had success using the newer Windows 10 Linux subsystem https://docs.microsoft.com/en-us/windows/wsl/install-win10 via the ubuntu distribution to package and deploy Lambda functions from Windows 10. I've not used Cygwin in quite some time.
I am having the same problem once I try to use custom created s3 bucket, cloudformation will fail at cresating s3 bucket. I wonder if I setup my BOOTSTRAP_BUCKET_PATH in wrong way. What exactly is BOOTSTRAP_BUCKET_PATH ? I couldn't find anywhere on internet.
BOOTSTRAP_BUCKET_PATH defined in config/env.mk is a string containing the values of BootstrapBucket and BootstrapPrefix joined by a "/" both of which are also parameters to the CloudFormation template. It would look something like "yourstackname-lexuibuildartifactbucket-146vrxfh5zag5/artifacts/aws-lex-web-ui/artifacts". The values identify where you want to output artifacts as a result of a build of the lex-web-ui. The CloudFormation template when run asks for the location of the BootstrapBucket and the BootstrapPrefix but does not update these. After the CloudFormation template is run, a new S3 bucket will contain the deployed lex-web-ui configured based on the supplied parameters. The "Bootstrap" parameters identify a staging area where the components can be deployed from.
I think one possible cause may be the case when you delete a bucket and then try and reuse the same name. The bucket name can be blocked for a while while AWS updates. I noticed this when trying to manually create the bucket in the console. When I tried using a bucket with a different name it worked and the CDK bootstrapping no longer hangs on create_in_progress. https://aws.amazon.com/premiumsupport/knowledge-center/s3-conflicting-conditional-operation/#:~:text=You%20can%20get%20the%20error,of%20deleting%20the%20original%20bucket.&text=However%2C%20when%20the%20bucket%20is,can%20use%20the%20bucket%20name.