Skip to content

Instantly share code, notes, and snippets.

@SevanBadal
Created June 27, 2025 02:51
Show Gist options
  • Select an option

  • Save SevanBadal/7810766efd197d428d06d0fd990ef111 to your computer and use it in GitHub Desktop.

Select an option

Save SevanBadal/7810766efd197d428d06d0fd990ef111 to your computer and use it in GitHub Desktop.
AWS Amplify Gen 2: REST API Lambda Function for Creating Cognito Users
// amplify/backend.ts
import { defineBackend } from "@aws-amplify/backend";
import { auth } from "./auth/resource";
import { data } from "./data/resource";
import { PolicyStatement, Effect } from "aws-cdk-lib/aws-iam";
import {
RestApi,
LambdaIntegration,
AuthorizationType,
CognitoUserPoolsAuthorizer,
} from "aws-cdk-lib/aws-apigateway";
import { createUser } from "./functions/create-user/resource";
import { Stack } from "aws-cdk-lib";
const backend = defineBackend({
auth,
data,
createUser,
});
// Create REST API Stack for user management
const apiStack = backend.createStack("UserManagementAPI");
// Create the REST API
const userApi = new RestApi(apiStack, "UserManagementRestApi", {
restApiName: "UserManagementAPI",
deployOptions: {
stageName: "prod",
},
defaultCorsPreflightOptions: {
allowOrigins: ["*"],
allowMethods: ["POST"],
allowHeaders: ["Content-Type", "Authorization"],
},
});
// Create Cognito authorizer using the auth resource
const cognitoAuthorizer = new CognitoUserPoolsAuthorizer(
apiStack,
"UserApiAuthorizer",
{
cognitoUserPools: [backend.auth.resources.userPool],
}
);
// Add the /users/create endpoint
const usersResource = userApi.root.addResource("users");
const createResource = usersResource.addResource("create");
// Add POST method with Lambda integration
createResource.addMethod(
"POST",
new LambdaIntegration(backend.createUser.resources.lambda),
{
authorizationType: AuthorizationType.COGNITO,
authorizer: cognitoAuthorizer,
}
);
// Grant Lambda permission to create users in Cognito
backend.createUser.resources.lambda.addToRolePolicy(
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
"cognito-idp:AdminCreateUser", // you only cognito-idp:AdminCreateUser for this example
"cognito-idp:AdminGetUser",
"cognito-idp:AdminSetUserPassword",
],
resources: [backend.auth.resources.userPool.userPoolArn],
})
);
backend.createUser.addEnvironment(
"AMPLIFY_AUTH_USERPOOL_ID",
backend.auth.resources.userPool.userPoolId
);
// Add the API URL to outputs
backend.addOutput({
custom: {
UserManagementAPI: userApi.url,
API: {
[userApi.restApiName]: {
endpoint: userApi.url,
region: Stack.of(userApi).region,
apiName: userApi.restApiName,
},
},
},
});
// amplify/functions/create-user/handler.ts
import { APIGatewayProxyHandler } from "aws-lambda";
import {
CognitoIdentityProviderClient,
AdminCreateUserCommand,
} from "@aws-sdk/client-cognito-identity-provider";
const env = process.env;
const cognito = new CognitoIdentityProviderClient();
export const handler: APIGatewayProxyHandler = async (event) => {
// Enable CORS
const headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type,Authorization",
"Content-Type": "application/json",
};
// Handle preflight requests
// if (event.httpMethod === "OPTIONS") {
// return {
// statusCode: 200,
// headers,
// body: "",
// };
// }
try {
// Check if user is authenticated (Amplify adds this to the event if the token is valid)
if (!event.requestContext.authorizer?.claims) {
return {
statusCode: 401,
headers,
body: JSON.stringify({ message: "Unauthorized" }),
};
}
// Parse request body
const { email, firstName, lastName, temporaryPassword } = JSON.parse(
event.body || "{}"
);
// Validate input
if (!email || !firstName || !lastName || !temporaryPassword) {
return {
statusCode: 400,
headers,
body: JSON.stringify({ message: "All fields are required" }),
};
}
if (temporaryPassword.length < 8) {
return {
statusCode: 400,
headers,
body: JSON.stringify({
message: "Password must be at least 8 characters long",
}),
};
}
// Use the User Pool ID from Amplify environment
const userPoolId = env.AMPLIFY_AUTH_USERPOOL_ID;
const command = new AdminCreateUserCommand({
UserPoolId: userPoolId,
Username: email,
UserAttributes: [
{
Name: "email",
Value: email,
},
{
Name: "given_name",
Value: firstName,
},
{
Name: "family_name",
Value: lastName,
},
{
Name: "email_verified",
Value: "true",
},
],
TemporaryPassword: temporaryPassword,
MessageAction: "SUPPRESS", // Remove to send welcome email
DesiredDeliveryMediums: ["EMAIL"],
});
const result = await cognito.send(command);
return {
statusCode: 201,
headers,
body: JSON.stringify({
message: "User created successfully",
user: {
username: result.User?.Username,
email: email,
status: result.User?.UserStatus,
},
}),
};
} catch (error: any) {
console.error("Error creating user:", error);
// Handle specific Cognito errors
if (error.code === "UsernameExistsException") {
return {
statusCode: 409,
headers,
body: JSON.stringify({
message: "A user with this email already exists",
}),
};
}
if (error.code === "InvalidPasswordException") {
return {
statusCode: 400,
headers,
body: JSON.stringify({
message: "Password does not meet requirements",
}),
};
}
return {
statusCode: 500,
headers,
body: JSON.stringify({ message: "Failed to create user" }),
};
}
};
// amplify/functions/create-user/resource.ts
import { defineFunction } from "@aws-amplify/backend";
export const createUser = defineFunction({
name: "create-user",
entry: "./handler.ts",
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment