Create AWS Connect Users

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 FREE

Frequently Asked Questions

Identity & Authentication
When do I need to provide a password for a Connect user?
Provide 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.
When should I use directoryUserId?
Use 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.
What are the username requirements for Connect users?
For non-SAML instances, usernames can include up to 20 characters. For SAML instances, usernames can include up to 64 characters from [a-zA-Z0-9_-.\@]+.
Configuration Requirements
What properties can't I change after creating a user?
Both name and instanceId are immutable and require resource replacement to change.
How many security profiles can I assign to a user?
You must assign between 1 and 10 security profiles using securityProfileIds.
What are the required fields for creating a Connect user?
Required fields are instanceId, name, routingProfileId, securityProfileIds, and phoneConfig. The password field is conditionally required based on your identity management type.
Phone Configuration
What's the difference between SOFT_PHONE and DESK_PHONE?
SOFT_PHONE uses the Amazon Connect interface for calls, while DESK_PHONE routes calls to an external phone number specified in deskPhoneNumber.
Can I configure email addresses for a user?
Yes, use the identityInfo block to set email and optionally secondaryEmail along with firstName and lastName.

Using a different cloud?

Explore integration guides for other cloud providers: