The aws:cognito/userPool:UserPool resource, part of the Pulumi AWS provider, defines a Cognito user pool that manages user registration, authentication, and account recovery. This guide focuses on three capabilities: basic pool creation, multi-factor authentication setup, and account recovery configuration.
User pools with SMS-based features require IAM roles with SNS permissions; most other features use AWS defaults unless explicitly configured. The examples are intentionally small. Combine them with your own email configuration, password policies, and Lambda triggers.
Create a user pool with minimal configuration
Most deployments start by creating a user pool with just a name, letting AWS apply defaults for authentication and verification.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const pool = new aws.cognito.UserPool("pool", {name: "mypool"});
import pulumi
import pulumi_aws as aws
pool = aws.cognito.UserPool("pool", name="mypool")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cognito"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := cognito.NewUserPool(ctx, "pool", &cognito.UserPoolArgs{
Name: pulumi.String("mypool"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var pool = new Aws.Cognito.UserPool("pool", new()
{
Name = "mypool",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cognito.UserPool;
import com.pulumi.aws.cognito.UserPoolArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var pool = new UserPool("pool", UserPoolArgs.builder()
.name("mypool")
.build());
}
}
resources:
pool:
type: aws:cognito:UserPool
properties:
name: mypool
The name property sets a unique identifier for the pool. Without additional configuration, the pool uses AWS defaults: MFA is disabled, passwords require basic complexity, and email verification is not configured. This minimal setup establishes the foundation for adding authentication features.
Enable SMS and authenticator app MFA
Applications requiring stronger security enable multi-factor authentication, allowing users to verify with SMS codes or authenticator apps.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.cognito.UserPool("example", {
mfaConfiguration: "ON",
smsAuthenticationMessage: "Your code is {####}",
smsConfiguration: {
externalId: "example",
snsCallerArn: exampleAwsIamRole.arn,
snsRegion: "us-east-1",
},
softwareTokenMfaConfiguration: {
enabled: true,
},
});
import pulumi
import pulumi_aws as aws
example = aws.cognito.UserPool("example",
mfa_configuration="ON",
sms_authentication_message="Your code is {####}",
sms_configuration={
"external_id": "example",
"sns_caller_arn": example_aws_iam_role["arn"],
"sns_region": "us-east-1",
},
software_token_mfa_configuration={
"enabled": True,
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cognito"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := cognito.NewUserPool(ctx, "example", &cognito.UserPoolArgs{
MfaConfiguration: pulumi.String("ON"),
SmsAuthenticationMessage: pulumi.String("Your code is {####}"),
SmsConfiguration: &cognito.UserPoolSmsConfigurationArgs{
ExternalId: pulumi.String("example"),
SnsCallerArn: pulumi.Any(exampleAwsIamRole.Arn),
SnsRegion: pulumi.String("us-east-1"),
},
SoftwareTokenMfaConfiguration: &cognito.UserPoolSoftwareTokenMfaConfigurationArgs{
Enabled: pulumi.Bool(true),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.Cognito.UserPool("example", new()
{
MfaConfiguration = "ON",
SmsAuthenticationMessage = "Your code is {####}",
SmsConfiguration = new Aws.Cognito.Inputs.UserPoolSmsConfigurationArgs
{
ExternalId = "example",
SnsCallerArn = exampleAwsIamRole.Arn,
SnsRegion = "us-east-1",
},
SoftwareTokenMfaConfiguration = new Aws.Cognito.Inputs.UserPoolSoftwareTokenMfaConfigurationArgs
{
Enabled = true,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cognito.UserPool;
import com.pulumi.aws.cognito.UserPoolArgs;
import com.pulumi.aws.cognito.inputs.UserPoolSmsConfigurationArgs;
import com.pulumi.aws.cognito.inputs.UserPoolSoftwareTokenMfaConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new UserPool("example", UserPoolArgs.builder()
.mfaConfiguration("ON")
.smsAuthenticationMessage("Your code is {####}")
.smsConfiguration(UserPoolSmsConfigurationArgs.builder()
.externalId("example")
.snsCallerArn(exampleAwsIamRole.arn())
.snsRegion("us-east-1")
.build())
.softwareTokenMfaConfiguration(UserPoolSoftwareTokenMfaConfigurationArgs.builder()
.enabled(true)
.build())
.build());
}
}
resources:
example:
type: aws:cognito:UserPool
properties:
mfaConfiguration: ON
smsAuthenticationMessage: Your code is {####}
smsConfiguration:
externalId: example
snsCallerArn: ${exampleAwsIamRole.arn}
snsRegion: us-east-1
softwareTokenMfaConfiguration:
enabled: true
Setting mfaConfiguration to “ON” requires all users to provide a second factor at sign-in. The smsConfiguration block defines the IAM role that sends SMS messages via SNS, while softwareTokenMfaConfiguration enables authenticator apps like Google Authenticator. The smsAuthenticationMessage template includes the {####} placeholder that Cognito replaces with the verification code.
Configure password recovery methods
User pools need recovery mechanisms so users can reset forgotten passwords through verified contact methods.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.cognito.UserPool("test", {
name: "mypool",
accountRecoverySetting: {
recoveryMechanisms: [
{
name: "verified_email",
priority: 1,
},
{
name: "verified_phone_number",
priority: 2,
},
],
},
});
import pulumi
import pulumi_aws as aws
test = aws.cognito.UserPool("test",
name="mypool",
account_recovery_setting={
"recovery_mechanisms": [
{
"name": "verified_email",
"priority": 1,
},
{
"name": "verified_phone_number",
"priority": 2,
},
],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cognito"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := cognito.NewUserPool(ctx, "test", &cognito.UserPoolArgs{
Name: pulumi.String("mypool"),
AccountRecoverySetting: &cognito.UserPoolAccountRecoverySettingArgs{
RecoveryMechanisms: cognito.UserPoolAccountRecoverySettingRecoveryMechanismArray{
&cognito.UserPoolAccountRecoverySettingRecoveryMechanismArgs{
Name: pulumi.String("verified_email"),
Priority: pulumi.Int(1),
},
&cognito.UserPoolAccountRecoverySettingRecoveryMechanismArgs{
Name: pulumi.String("verified_phone_number"),
Priority: pulumi.Int(2),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var test = new Aws.Cognito.UserPool("test", new()
{
Name = "mypool",
AccountRecoverySetting = new Aws.Cognito.Inputs.UserPoolAccountRecoverySettingArgs
{
RecoveryMechanisms = new[]
{
new Aws.Cognito.Inputs.UserPoolAccountRecoverySettingRecoveryMechanismArgs
{
Name = "verified_email",
Priority = 1,
},
new Aws.Cognito.Inputs.UserPoolAccountRecoverySettingRecoveryMechanismArgs
{
Name = "verified_phone_number",
Priority = 2,
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cognito.UserPool;
import com.pulumi.aws.cognito.UserPoolArgs;
import com.pulumi.aws.cognito.inputs.UserPoolAccountRecoverySettingArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var test = new UserPool("test", UserPoolArgs.builder()
.name("mypool")
.accountRecoverySetting(UserPoolAccountRecoverySettingArgs.builder()
.recoveryMechanisms(
UserPoolAccountRecoverySettingRecoveryMechanismArgs.builder()
.name("verified_email")
.priority(1)
.build(),
UserPoolAccountRecoverySettingRecoveryMechanismArgs.builder()
.name("verified_phone_number")
.priority(2)
.build())
.build())
.build());
}
}
resources:
test:
type: aws:cognito:UserPool
properties:
name: mypool
accountRecoverySetting:
recoveryMechanisms:
- name: verified_email
priority: 1
- name: verified_phone_number
priority: 2
The accountRecoverySetting block defines which verified attributes users can use for password recovery. The priority field determines the order: verified email is tried first, then verified phone number. Users must have at least one verified recovery method to reset their password.
Beyond these examples
These snippets focus on specific user pool features: basic pool creation, multi-factor authentication (SMS and software tokens), and account recovery configuration. They’re intentionally minimal rather than full authentication systems.
The examples may reference pre-existing infrastructure such as IAM roles with SNS permissions for SMS delivery. They focus on configuring the user pool rather than provisioning surrounding infrastructure.
To keep things focused, common user pool patterns are omitted, including:
- Email configuration (emailConfiguration for SES integration)
- Password policies (passwordPolicy for complexity requirements)
- Custom attributes and schemas
- Lambda triggers for authentication workflows
- Advanced security features (userPoolAddOns)
- Username and alias configuration
These omissions are intentional: the goal is to illustrate how each user pool feature is wired, not provide drop-in authentication modules. See the Cognito User Pool resource reference for all available configuration options.
Let's create AWS Cognito User Pools
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Multi-Factor Authentication (MFA)
mfaConfiguration is set to ON or OPTIONAL, you must configure at least one MFA method: emailMfaConfiguration, smsConfiguration, or softwareTokenMfaConfiguration.mfaConfiguration to ON, configure smsConfiguration with externalId, snsCallerArn, and snsRegion, and set softwareTokenMfaConfiguration.enabled to true.accountRecoverySetting entries and an emailConfiguration block. It only works when mfaConfiguration is ON or OPTIONAL.mfaConfiguration is set to ON or OPTIONAL along with a configured smsConfiguration block.Immutable Properties & Schema
aliasAttributes and usernameAttributes are immutable. Schema attributes can be added but never modified or removed (maximum 50 attributes).pulumi taint to force recreation if you need to remove it.Username & Alias Configuration
aliasAttributes allows users to sign in with phone_number, email, or preferred_username as aliases. usernameAttributes lets users sign up with email or phone as their username. These properties conflict and cannot be used together.Verification Messages
emailVerificationMessage conflicts with verificationMessageTemplate.emailMessage, emailVerificationSubject conflicts with verificationMessageTemplate.emailSubject, and smsVerificationMessage conflicts with verificationMessageTemplate.smsMessage.smsAuthenticationMessage must contain the {####} placeholder, which gets replaced with the authentication code.Account Recovery & Protection
accountRecoverySetting with a recoveryMechanisms array. Specify name (verified_email or verified_phone_number) and priority for each mechanism.deletionProtection to ACTIVE to prevent accidental deletion (default is INACTIVE). You must deactivate it before you can delete the user pool.