The aws:connect/user:User resource, part of the Pulumi AWS provider, defines Amazon Connect agent users: their identity, authentication, phone settings, and organizational placement. This guide focuses on four capabilities: basic user provisioning with soft phones, organizational hierarchy assignment, email contact information, and desk phone configuration with multiple security profiles.
Connect users belong to a Connect instance and reference routing profiles, security profiles, and optionally hierarchy groups. The examples are intentionally small. Combine them with your own Connect instance, routing configuration, and organizational structure.
Create a user with soft phone configuration
Most contact center deployments start by provisioning agent users with basic identity and soft phone settings for browser-based calling.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.connect.User("example", {
instanceId: exampleAwsConnectInstance.id,
name: "example",
password: "Password123",
routingProfileId: exampleAwsConnectRoutingProfile.routingProfileId,
securityProfileIds: [exampleAwsConnectSecurityProfile.securityProfileId],
identityInfo: {
firstName: "example",
lastName: "example2",
},
phoneConfig: {
afterContactWorkTimeLimit: 0,
phoneType: "SOFT_PHONE",
},
});
import pulumi
import pulumi_aws as aws
example = aws.connect.User("example",
instance_id=example_aws_connect_instance["id"],
name="example",
password="Password123",
routing_profile_id=example_aws_connect_routing_profile["routingProfileId"],
security_profile_ids=[example_aws_connect_security_profile["securityProfileId"]],
identity_info={
"first_name": "example",
"last_name": "example2",
},
phone_config={
"after_contact_work_time_limit": 0,
"phone_type": "SOFT_PHONE",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := connect.NewUser(ctx, "example", &connect.UserArgs{
InstanceId: pulumi.Any(exampleAwsConnectInstance.Id),
Name: pulumi.String("example"),
Password: pulumi.String("Password123"),
RoutingProfileId: pulumi.Any(exampleAwsConnectRoutingProfile.RoutingProfileId),
SecurityProfileIds: pulumi.StringArray{
exampleAwsConnectSecurityProfile.SecurityProfileId,
},
IdentityInfo: &connect.UserIdentityInfoArgs{
FirstName: pulumi.String("example"),
LastName: pulumi.String("example2"),
},
PhoneConfig: &connect.UserPhoneConfigArgs{
AfterContactWorkTimeLimit: pulumi.Int(0),
PhoneType: pulumi.String("SOFT_PHONE"),
},
})
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.Connect.User("example", new()
{
InstanceId = exampleAwsConnectInstance.Id,
Name = "example",
Password = "Password123",
RoutingProfileId = exampleAwsConnectRoutingProfile.RoutingProfileId,
SecurityProfileIds = new[]
{
exampleAwsConnectSecurityProfile.SecurityProfileId,
},
IdentityInfo = new Aws.Connect.Inputs.UserIdentityInfoArgs
{
FirstName = "example",
LastName = "example2",
},
PhoneConfig = new Aws.Connect.Inputs.UserPhoneConfigArgs
{
AfterContactWorkTimeLimit = 0,
PhoneType = "SOFT_PHONE",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.User;
import com.pulumi.aws.connect.UserArgs;
import com.pulumi.aws.connect.inputs.UserIdentityInfoArgs;
import com.pulumi.aws.connect.inputs.UserPhoneConfigArgs;
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 User("example", UserArgs.builder()
.instanceId(exampleAwsConnectInstance.id())
.name("example")
.password("Password123")
.routingProfileId(exampleAwsConnectRoutingProfile.routingProfileId())
.securityProfileIds(exampleAwsConnectSecurityProfile.securityProfileId())
.identityInfo(UserIdentityInfoArgs.builder()
.firstName("example")
.lastName("example2")
.build())
.phoneConfig(UserPhoneConfigArgs.builder()
.afterContactWorkTimeLimit(0)
.phoneType("SOFT_PHONE")
.build())
.build());
}
}
resources:
example:
type: aws:connect:User
properties:
instanceId: ${exampleAwsConnectInstance.id}
name: example
password: Password123
routingProfileId: ${exampleAwsConnectRoutingProfile.routingProfileId}
securityProfileIds:
- ${exampleAwsConnectSecurityProfile.securityProfileId}
identityInfo:
firstName: example
lastName: example2
phoneConfig:
afterContactWorkTimeLimit: 0
phoneType: SOFT_PHONE
The instanceId places the user in a specific Connect instance. The routingProfileId determines which queues the agent can handle. The securityProfileIds array grants permissions (minimum 1, maximum 10 profiles). The phoneConfig block sets phoneType to SOFT_PHONE for browser-based calling, and afterContactWorkTimeLimit controls post-call wrap-up time in seconds. The password property is required when using Connect for identity management rather than SAML or Active Directory.
Assign users to organizational hierarchy groups
Contact centers organize agents into teams or departments using hierarchy groups for reporting and permissions inheritance.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.connect.User("example", {
instanceId: exampleAwsConnectInstance.id,
name: "example",
password: "Password123",
routingProfileId: exampleAwsConnectRoutingProfile.routingProfileId,
hierarchyGroupId: exampleAwsConnectUserHierarchyGroup.hierarchyGroupId,
securityProfileIds: [exampleAwsConnectSecurityProfile.securityProfileId],
identityInfo: {
firstName: "example",
lastName: "example2",
},
phoneConfig: {
afterContactWorkTimeLimit: 0,
phoneType: "SOFT_PHONE",
},
});
import pulumi
import pulumi_aws as aws
example = aws.connect.User("example",
instance_id=example_aws_connect_instance["id"],
name="example",
password="Password123",
routing_profile_id=example_aws_connect_routing_profile["routingProfileId"],
hierarchy_group_id=example_aws_connect_user_hierarchy_group["hierarchyGroupId"],
security_profile_ids=[example_aws_connect_security_profile["securityProfileId"]],
identity_info={
"first_name": "example",
"last_name": "example2",
},
phone_config={
"after_contact_work_time_limit": 0,
"phone_type": "SOFT_PHONE",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := connect.NewUser(ctx, "example", &connect.UserArgs{
InstanceId: pulumi.Any(exampleAwsConnectInstance.Id),
Name: pulumi.String("example"),
Password: pulumi.String("Password123"),
RoutingProfileId: pulumi.Any(exampleAwsConnectRoutingProfile.RoutingProfileId),
HierarchyGroupId: pulumi.Any(exampleAwsConnectUserHierarchyGroup.HierarchyGroupId),
SecurityProfileIds: pulumi.StringArray{
exampleAwsConnectSecurityProfile.SecurityProfileId,
},
IdentityInfo: &connect.UserIdentityInfoArgs{
FirstName: pulumi.String("example"),
LastName: pulumi.String("example2"),
},
PhoneConfig: &connect.UserPhoneConfigArgs{
AfterContactWorkTimeLimit: pulumi.Int(0),
PhoneType: pulumi.String("SOFT_PHONE"),
},
})
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.Connect.User("example", new()
{
InstanceId = exampleAwsConnectInstance.Id,
Name = "example",
Password = "Password123",
RoutingProfileId = exampleAwsConnectRoutingProfile.RoutingProfileId,
HierarchyGroupId = exampleAwsConnectUserHierarchyGroup.HierarchyGroupId,
SecurityProfileIds = new[]
{
exampleAwsConnectSecurityProfile.SecurityProfileId,
},
IdentityInfo = new Aws.Connect.Inputs.UserIdentityInfoArgs
{
FirstName = "example",
LastName = "example2",
},
PhoneConfig = new Aws.Connect.Inputs.UserPhoneConfigArgs
{
AfterContactWorkTimeLimit = 0,
PhoneType = "SOFT_PHONE",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.User;
import com.pulumi.aws.connect.UserArgs;
import com.pulumi.aws.connect.inputs.UserIdentityInfoArgs;
import com.pulumi.aws.connect.inputs.UserPhoneConfigArgs;
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 User("example", UserArgs.builder()
.instanceId(exampleAwsConnectInstance.id())
.name("example")
.password("Password123")
.routingProfileId(exampleAwsConnectRoutingProfile.routingProfileId())
.hierarchyGroupId(exampleAwsConnectUserHierarchyGroup.hierarchyGroupId())
.securityProfileIds(exampleAwsConnectSecurityProfile.securityProfileId())
.identityInfo(UserIdentityInfoArgs.builder()
.firstName("example")
.lastName("example2")
.build())
.phoneConfig(UserPhoneConfigArgs.builder()
.afterContactWorkTimeLimit(0)
.phoneType("SOFT_PHONE")
.build())
.build());
}
}
resources:
example:
type: aws:connect:User
properties:
instanceId: ${exampleAwsConnectInstance.id}
name: example
password: Password123
routingProfileId: ${exampleAwsConnectRoutingProfile.routingProfileId}
hierarchyGroupId: ${exampleAwsConnectUserHierarchyGroup.hierarchyGroupId}
securityProfileIds:
- ${exampleAwsConnectSecurityProfile.securityProfileId}
identityInfo:
firstName: example
lastName: example2
phoneConfig:
afterContactWorkTimeLimit: 0
phoneType: SOFT_PHONE
The hierarchyGroupId property places the user within your organizational structure. Hierarchy groups control reporting relationships and can inherit security settings from parent groups. This extends the basic configuration by adding organizational context.
Add contact information to user profiles
Agent profiles often store email addresses for notifications, password resets, and external system integration.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.connect.User("example", {
instanceId: exampleAwsConnectInstance.id,
name: "example",
password: "Password123",
routingProfileId: exampleAwsConnectRoutingProfile.routingProfileId,
securityProfileIds: [exampleAwsConnectSecurityProfile.securityProfileId],
identityInfo: {
email: "example@example.com",
firstName: "example",
lastName: "example2",
secondaryEmail: "secondary@example.com",
},
phoneConfig: {
afterContactWorkTimeLimit: 0,
phoneType: "SOFT_PHONE",
},
});
import pulumi
import pulumi_aws as aws
example = aws.connect.User("example",
instance_id=example_aws_connect_instance["id"],
name="example",
password="Password123",
routing_profile_id=example_aws_connect_routing_profile["routingProfileId"],
security_profile_ids=[example_aws_connect_security_profile["securityProfileId"]],
identity_info={
"email": "example@example.com",
"first_name": "example",
"last_name": "example2",
"secondary_email": "secondary@example.com",
},
phone_config={
"after_contact_work_time_limit": 0,
"phone_type": "SOFT_PHONE",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := connect.NewUser(ctx, "example", &connect.UserArgs{
InstanceId: pulumi.Any(exampleAwsConnectInstance.Id),
Name: pulumi.String("example"),
Password: pulumi.String("Password123"),
RoutingProfileId: pulumi.Any(exampleAwsConnectRoutingProfile.RoutingProfileId),
SecurityProfileIds: pulumi.StringArray{
exampleAwsConnectSecurityProfile.SecurityProfileId,
},
IdentityInfo: &connect.UserIdentityInfoArgs{
Email: pulumi.String("example@example.com"),
FirstName: pulumi.String("example"),
LastName: pulumi.String("example2"),
SecondaryEmail: pulumi.String("secondary@example.com"),
},
PhoneConfig: &connect.UserPhoneConfigArgs{
AfterContactWorkTimeLimit: pulumi.Int(0),
PhoneType: pulumi.String("SOFT_PHONE"),
},
})
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.Connect.User("example", new()
{
InstanceId = exampleAwsConnectInstance.Id,
Name = "example",
Password = "Password123",
RoutingProfileId = exampleAwsConnectRoutingProfile.RoutingProfileId,
SecurityProfileIds = new[]
{
exampleAwsConnectSecurityProfile.SecurityProfileId,
},
IdentityInfo = new Aws.Connect.Inputs.UserIdentityInfoArgs
{
Email = "example@example.com",
FirstName = "example",
LastName = "example2",
SecondaryEmail = "secondary@example.com",
},
PhoneConfig = new Aws.Connect.Inputs.UserPhoneConfigArgs
{
AfterContactWorkTimeLimit = 0,
PhoneType = "SOFT_PHONE",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.User;
import com.pulumi.aws.connect.UserArgs;
import com.pulumi.aws.connect.inputs.UserIdentityInfoArgs;
import com.pulumi.aws.connect.inputs.UserPhoneConfigArgs;
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 User("example", UserArgs.builder()
.instanceId(exampleAwsConnectInstance.id())
.name("example")
.password("Password123")
.routingProfileId(exampleAwsConnectRoutingProfile.routingProfileId())
.securityProfileIds(exampleAwsConnectSecurityProfile.securityProfileId())
.identityInfo(UserIdentityInfoArgs.builder()
.email("example@example.com")
.firstName("example")
.lastName("example2")
.secondaryEmail("secondary@example.com")
.build())
.phoneConfig(UserPhoneConfigArgs.builder()
.afterContactWorkTimeLimit(0)
.phoneType("SOFT_PHONE")
.build())
.build());
}
}
resources:
example:
type: aws:connect:User
properties:
instanceId: ${exampleAwsConnectInstance.id}
name: example
password: Password123
routingProfileId: ${exampleAwsConnectRoutingProfile.routingProfileId}
securityProfileIds:
- ${exampleAwsConnectSecurityProfile.securityProfileId}
identityInfo:
email: example@example.com
firstName: example
lastName: example2
secondaryEmail: secondary@example.com
phoneConfig:
afterContactWorkTimeLimit: 0
phoneType: SOFT_PHONE
The identityInfo block accepts email and secondaryEmail properties for primary and backup contact addresses. Connect uses these for system notifications and account recovery. The firstName and lastName properties remain required for agent identification.
Configure desk phone with multiple security profiles
Some agents need physical desk phones and require multiple security profiles to access different features or queues.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.connect.User("example", {
instanceId: exampleAwsConnectInstance.id,
name: "example",
password: "Password123",
routingProfileId: exampleAwsConnectRoutingProfile.routingProfileId,
securityProfileIds: [
exampleAwsConnectSecurityProfile.securityProfileId,
example2.securityProfileId,
],
phoneConfig: {
afterContactWorkTimeLimit: 0,
autoAccept: false,
deskPhoneNumber: "+112345678912",
phoneType: "DESK_PHONE",
},
});
import pulumi
import pulumi_aws as aws
example = aws.connect.User("example",
instance_id=example_aws_connect_instance["id"],
name="example",
password="Password123",
routing_profile_id=example_aws_connect_routing_profile["routingProfileId"],
security_profile_ids=[
example_aws_connect_security_profile["securityProfileId"],
example2["securityProfileId"],
],
phone_config={
"after_contact_work_time_limit": 0,
"auto_accept": False,
"desk_phone_number": "+112345678912",
"phone_type": "DESK_PHONE",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := connect.NewUser(ctx, "example", &connect.UserArgs{
InstanceId: pulumi.Any(exampleAwsConnectInstance.Id),
Name: pulumi.String("example"),
Password: pulumi.String("Password123"),
RoutingProfileId: pulumi.Any(exampleAwsConnectRoutingProfile.RoutingProfileId),
SecurityProfileIds: pulumi.StringArray{
exampleAwsConnectSecurityProfile.SecurityProfileId,
example2.SecurityProfileId,
},
PhoneConfig: &connect.UserPhoneConfigArgs{
AfterContactWorkTimeLimit: pulumi.Int(0),
AutoAccept: pulumi.Bool(false),
DeskPhoneNumber: pulumi.String("+112345678912"),
PhoneType: pulumi.String("DESK_PHONE"),
},
})
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.Connect.User("example", new()
{
InstanceId = exampleAwsConnectInstance.Id,
Name = "example",
Password = "Password123",
RoutingProfileId = exampleAwsConnectRoutingProfile.RoutingProfileId,
SecurityProfileIds = new[]
{
exampleAwsConnectSecurityProfile.SecurityProfileId,
example2.SecurityProfileId,
},
PhoneConfig = new Aws.Connect.Inputs.UserPhoneConfigArgs
{
AfterContactWorkTimeLimit = 0,
AutoAccept = false,
DeskPhoneNumber = "+112345678912",
PhoneType = "DESK_PHONE",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.User;
import com.pulumi.aws.connect.UserArgs;
import com.pulumi.aws.connect.inputs.UserPhoneConfigArgs;
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 User("example", UserArgs.builder()
.instanceId(exampleAwsConnectInstance.id())
.name("example")
.password("Password123")
.routingProfileId(exampleAwsConnectRoutingProfile.routingProfileId())
.securityProfileIds(
exampleAwsConnectSecurityProfile.securityProfileId(),
example2.securityProfileId())
.phoneConfig(UserPhoneConfigArgs.builder()
.afterContactWorkTimeLimit(0)
.autoAccept(false)
.deskPhoneNumber("+112345678912")
.phoneType("DESK_PHONE")
.build())
.build());
}
}
resources:
example:
type: aws:connect:User
properties:
instanceId: ${exampleAwsConnectInstance.id}
name: example
password: Password123
routingProfileId: ${exampleAwsConnectRoutingProfile.routingProfileId}
securityProfileIds:
- ${exampleAwsConnectSecurityProfile.securityProfileId}
- ${example2.securityProfileId}
phoneConfig:
afterContactWorkTimeLimit: 0
autoAccept: false
deskPhoneNumber: '+112345678912'
phoneType: DESK_PHONE
When phoneType is DESK_PHONE, the deskPhoneNumber property specifies the physical phone to ring. The autoAccept property controls whether calls connect automatically or require manual answer. The securityProfileIds array can include multiple profiles, combining permissions from each. This configuration suits agents who need broader access across different contact center functions.
Beyond these examples
These snippets focus on specific user-level features: user identity and authentication, phone configuration, and organizational hierarchy and security profiles. They’re intentionally minimal rather than full contact center deployments.
The examples reference pre-existing infrastructure such as Amazon Connect instances, and routing profiles, security profiles, and hierarchy groups. They focus on configuring the user rather than provisioning the surrounding Connect infrastructure.
To keep things focused, common user patterns are omitted, including:
- Directory integration (directoryUserId for SAML/AD)
- Tags for cost allocation and organization
- After-contact work time limits (afterContactWorkTimeLimit)
These omissions are intentional: the goal is to illustrate how each user feature is wired, not provide drop-in contact center modules. See the Connect User resource reference for all available configuration options.
Let's create AWS Connect Users
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Identity & Authentication
password only if you’re using Amazon Connect for identity management. If you’re using SAML or an external directory, including a password causes an error.directoryUserId when Amazon Connect cannot access your directory to authenticate users. Don’t include it if you’re using SAML for identity management, as this returns an error.[a-zA-Z0-9_-.\@]+.Configuration Requirements
name and instanceId are immutable and require resource replacement to change.securityProfileIds.instanceId, name, routingProfileId, securityProfileIds, and phoneConfig. The password field is conditionally required based on your identity management type.Phone Configuration
deskPhoneNumber.identityInfo block to set email and optionally secondaryEmail along with firstName and lastName.Using a different cloud?
Explore integration guides for other cloud providers: