The aws:elasticache/user:User resource, part of the Pulumi AWS provider, defines ElastiCache users with authentication methods and Redis command permissions. This guide focuses on three capabilities: password and IAM authentication, Redis command access control via access strings, and password rotation with dual credentials.
ElastiCache users authenticate to clusters and must be assigned to user groups to grant actual access. The examples are intentionally small. Combine them with UserGroup resources and cluster configuration for complete access control.
Grant scoped Redis command access with passwords
Most deployments create users with specific command permissions and password authentication, enabling least-privilege access patterns.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.elasticache.User("test", {
userId: "testUserId",
userName: "testUserName",
accessString: "on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember",
engine: "redis",
passwords: ["password123456789"],
});
import pulumi
import pulumi_aws as aws
test = aws.elasticache.User("test",
user_id="testUserId",
user_name="testUserName",
access_string="on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember",
engine="redis",
passwords=["password123456789"])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/elasticache"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := elasticache.NewUser(ctx, "test", &elasticache.UserArgs{
UserId: pulumi.String("testUserId"),
UserName: pulumi.String("testUserName"),
AccessString: pulumi.String("on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember"),
Engine: pulumi.String("redis"),
Passwords: pulumi.StringArray{
pulumi.String("password123456789"),
},
})
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.ElastiCache.User("test", new()
{
UserId = "testUserId",
UserName = "testUserName",
AccessString = "on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember",
Engine = "redis",
Passwords = new[]
{
"password123456789",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.elasticache.User;
import com.pulumi.aws.elasticache.UserArgs;
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 User("test", UserArgs.builder()
.userId("testUserId")
.userName("testUserName")
.accessString("on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember")
.engine("redis")
.passwords("password123456789")
.build());
}
}
resources:
test:
type: aws:elasticache:User
properties:
userId: testUserId
userName: testUserName
accessString: on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember
engine: redis
passwords:
- password123456789
The accessString property controls which Redis commands and key patterns the user can execute. The syntax follows the pattern on ~keypattern +@category -command, where on enables the user, ~app::* restricts access to keys matching that pattern, and the command list grants read operations while denying writes. The passwords array holds up to two passwords for authentication.
Authenticate users with IAM credentials
Teams using AWS IAM for centralized identity management can authenticate through IAM instead of managing separate passwords.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.elasticache.User("test", {
userId: "testUserId",
userName: "testUserName",
accessString: "on ~* +@all",
engine: "redis",
authenticationMode: {
type: "iam",
},
});
import pulumi
import pulumi_aws as aws
test = aws.elasticache.User("test",
user_id="testUserId",
user_name="testUserName",
access_string="on ~* +@all",
engine="redis",
authentication_mode={
"type": "iam",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/elasticache"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := elasticache.NewUser(ctx, "test", &elasticache.UserArgs{
UserId: pulumi.String("testUserId"),
UserName: pulumi.String("testUserName"),
AccessString: pulumi.String("on ~* +@all"),
Engine: pulumi.String("redis"),
AuthenticationMode: &elasticache.UserAuthenticationModeArgs{
Type: pulumi.String("iam"),
},
})
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.ElastiCache.User("test", new()
{
UserId = "testUserId",
UserName = "testUserName",
AccessString = "on ~* +@all",
Engine = "redis",
AuthenticationMode = new Aws.ElastiCache.Inputs.UserAuthenticationModeArgs
{
Type = "iam",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.elasticache.User;
import com.pulumi.aws.elasticache.UserArgs;
import com.pulumi.aws.elasticache.inputs.UserAuthenticationModeArgs;
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 User("test", UserArgs.builder()
.userId("testUserId")
.userName("testUserName")
.accessString("on ~* +@all")
.engine("redis")
.authenticationMode(UserAuthenticationModeArgs.builder()
.type("iam")
.build())
.build());
}
}
resources:
test:
type: aws:elasticache:User
properties:
userId: testUserId
userName: testUserName
accessString: on ~* +@all
engine: redis
authenticationMode:
type: iam
The authenticationMode property switches from password to IAM authentication. When type is set to iam, users authenticate with AWS credentials rather than ElastiCache-specific passwords. This requires IAM permissions to connect to ElastiCache.
Configure password rotation with dual passwords
Password rotation requires supporting both old and new credentials during the transition period to avoid service interruption.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const test = new aws.elasticache.User("test", {
userId: "testUserId",
userName: "testUserName",
accessString: "on ~* +@all",
engine: "redis",
authenticationMode: {
type: "password",
passwords: [
"password1",
"password2",
],
},
});
import pulumi
import pulumi_aws as aws
test = aws.elasticache.User("test",
user_id="testUserId",
user_name="testUserName",
access_string="on ~* +@all",
engine="redis",
authentication_mode={
"type": "password",
"passwords": [
"password1",
"password2",
],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/elasticache"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := elasticache.NewUser(ctx, "test", &elasticache.UserArgs{
UserId: pulumi.String("testUserId"),
UserName: pulumi.String("testUserName"),
AccessString: pulumi.String("on ~* +@all"),
Engine: pulumi.String("redis"),
AuthenticationMode: &elasticache.UserAuthenticationModeArgs{
Type: pulumi.String("password"),
Passwords: pulumi.StringArray{
pulumi.String("password1"),
pulumi.String("password2"),
},
},
})
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.ElastiCache.User("test", new()
{
UserId = "testUserId",
UserName = "testUserName",
AccessString = "on ~* +@all",
Engine = "redis",
AuthenticationMode = new Aws.ElastiCache.Inputs.UserAuthenticationModeArgs
{
Type = "password",
Passwords = new[]
{
"password1",
"password2",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.elasticache.User;
import com.pulumi.aws.elasticache.UserArgs;
import com.pulumi.aws.elasticache.inputs.UserAuthenticationModeArgs;
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 User("test", UserArgs.builder()
.userId("testUserId")
.userName("testUserName")
.accessString("on ~* +@all")
.engine("redis")
.authenticationMode(UserAuthenticationModeArgs.builder()
.type("password")
.passwords(
"password1",
"password2")
.build())
.build());
}
}
resources:
test:
type: aws:elasticache:User
properties:
userId: testUserId
userName: testUserName
accessString: on ~* +@all
engine: redis
authenticationMode:
type: password
passwords:
- password1
- password2
ElastiCache allows up to two passwords per user. During rotation, add the new password to the passwords array in authenticationMode, update client applications to use the new credential, then remove the old password. This enables zero-downtime rotation.
Beyond these examples
These snippets focus on specific user-level features: password and IAM authentication, Redis command access control, and password rotation support. They’re intentionally minimal rather than full access control configurations.
The examples may reference pre-existing infrastructure such as IAM permissions for IAM-authenticated users. They focus on configuring the user rather than provisioning clusters or user groups.
To keep things focused, common user patterns are omitted, including:
- User group membership (requires separate UserGroup resource)
- No-password authentication (noPasswordRequired)
- Tagging for organization and cost tracking
- Multi-region user management
These omissions are intentional: the goal is to illustrate how each user feature is wired, not provide drop-in access control modules. See the ElastiCache User resource reference for all available configuration options.
Let's create AWS ElastiCache Users
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Security & Authentication
authenticationMode.type to iam) or password authentication (set authenticationMode.type to password with a passwords array).passwords field or nest passwords within authenticationMode when type is password.Configuration & Immutability
userId and userName are immutable properties. Changing either will force replacement of the entire resource.accessString is a required field that defines access permissions for the user. See the AWS documentation on Specifying Permissions Using an Access String for syntax details.Engine Support
redis and valkey (case insensitive).