I use cloudformation template from other AWS account but today I have this error:
Resource handler returned message: "Invalid request provided: AWS::Cognito::UserPoolUser" (RequestToken: d55c7a26-473f-3eda-b1af-fdc97afc5364, HandlerErrorCode: InvalidRequest)
My cloudformation template:
CGNAdminUser:
Type: AWS::Cognito::UserPoolUser
Properties:
DesiredDeliveryMediums:
- EMAIL
UserAttributes:
- Name: email
Value: !Ref Email
Username: !Ref Username
UserPoolId: !Ref CGNUserPool
I try add this but do not work:
DependsOn: CGNUserPool
I try change UserPoolId: !Ref CGNUserPool UserPoolId
by UserPoolId: !GetAtt CGNUserPool.UserPoolId
but do not work again
May be AWS bug today because, my user is created !!
Check if you have a CustomMessage
attribute in your CGNuserPool
.
If so, it may be this one that fails.
Checkout if you have an event named AdminCreateUser
in your CloudTrail (you can access it from CloudFormation console under the stack that failed, you should have a link named "View the CloudTrail events for this resource".
In the CloudTrail event, check in Event record if you have an entry named errorMessage
. You'll have the root error.
If you need your DynamoDB to have data inserted while creating, the problem has been solved here: PutItem in DynamoDB table by CloudFormation
Solution is to create a custom resource like:
UsersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Sub "${AWS::StackName}-my-users-table"
AttributeDefinitions:
-
AttributeName: "username"
AttributeType: "S"
KeySchema:
-
AttributeName: "username"
KeyType: "HASH"
MyFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "${AWS::StackName}-PopulateTable"
Environment:
Variables:
TABLE_NAME: !Ref UsersTable
USERNAME: !Ref Username
EMAIL: !Ref Email
CodeUri: src/populateFunction
Role: #an execution role defined
SetData:
Type: Custom::InitFunction
DependsOn: MyFunction
Properties:
ServiceToken: !GetAtt MyFunction.Arn
And under src/populateFunction/index.js your function should contain:
const axios = require('axios');
exports.handler = async function(event, context) {
if (event.RequestType !== "Create") {
console.log("Not a Create request, exiting.");
const responseBody = JSON.stringify({
Status: "SUCCESS",
Reason: "No action needed.",
PhysicalResourceId: context.logStreamName,
StackId: event.StackId,
RequestId: event.RequestId,
LogicalResourceId: event.LogicalResourceId
});
console.log("Sending response to CloudFormation:", responseBody);
try {
await axios.put(event.ResponseURL, responseBody, { headers: { "Content-Type": "" } });
} catch (err) {
console.error("Failed to send response to CloudFormation:", err);
}
return;
}
// Your function
}
Else, CloudFormation will run for hours waiting for your function...
Finally you can insert your cognito config and don't forget to make it depends on your user table (DependsOn: !Ref UsersTable
)