Repository: mrparkers/terraform-provider-keycloak
Pull request #159 (2019-10-02 11:39:10)

New resource openid_user_realm_role_protocol_mapper
This adds keycloak_openid_user_realm_role_protocol_mapper.

Some apparently unrelated failures on tests:

```
$ make testacc
?   	github.com/mrparkers/terraform-provider-keycloak	[no test files]
=== RUN   TestAccKeycloakApiClientRefresh
--- PASS: TestAccKeycloakApiClientRefresh (1.30s)
=== RUN   TestLocationHeaderParseForClient
--- PASS: TestLocationHeaderParseForClient (0.00s)
=== RUN   TestLocationHeaderParseForComponent
--- PASS: TestLocationHeaderParseForComponent (0.00s)
PASS
ok  	github.com/mrparkers/terraform-provider-keycloak/keycloak	(cached)
=== RUN   TestAccKeycloakDataSourceOpenidClientAuthorizationPolicy_basic
--- PASS: TestAccKeycloakDataSourceOpenidClientAuthorizationPolicy_basic (0.96s)
=== RUN   TestAccKeycloakDataSourceOpenidClient_basic
--- PASS: TestAccKeycloakDataSourceOpenidClient_basic (1.02s)
=== RUN   TestAccKeycloakDataSourceRealmKeys_basic
--- PASS: TestAccKeycloakDataSourceRealmKeys_basic (0.83s)
=== RUN   TestAccKeycloakDataSourceRealmKeys_filterByAlgorithms
--- PASS: TestAccKeycloakDataSourceRealmKeys_filterByAlgorithms (1.15s)
=== RUN   TestAccKeycloakDataSourceRole_basic
--- PASS: TestAccKeycloakDataSourceRole_basic (1.19s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_clientDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_clientDuplicateNameValidation (1.35s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_clientScopeDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_clientScopeDuplicateNameValidation (1.16s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_clientDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_clientDuplicateNameValidation (1.06s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_clientScopeDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_clientScopeDuplicateNameValidation (1.19s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_clientDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_clientDuplicateNameValidation (1.17s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_clientScopeDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_clientScopeDuplicateNameValidation (1.23s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_clientDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_clientDuplicateNameValidation (0.89s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_clientScopeDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_clientScopeDuplicateNameValidation (0.86s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_clientDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_clientDuplicateNameValidation (0.84s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_clientScopeDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_clientScopeDuplicateNameValidation (0.98s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_clientScopeDuplicateNameValidation
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_clientScopeDuplicateNameValidation (1.07s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_validateClientOrClientScopeSet
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_validateClientOrClientScopeSet (0.70s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_validateClientOrClientScopeSet
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_validateClientOrClientScopeSet (0.64s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_validateClientOrClientScopeSet
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_validateClientOrClientScopeSet (0.70s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_validateClientOrClientScopeSet
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_validateClientOrClientScopeSet (0.72s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_validateClientOrClientScopeSet
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_validateClientOrClientScopeSet (0.63s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_validateClientOrClientScopeSet
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_validateClientOrClientScopeSet (0.78s)
=== RUN   TestAccKeycloakProvider_passwordGrant
--- SKIP: TestAccKeycloakProvider_passwordGrant (0.00s)
    test_utils.go:63: Environment variable KEYCLOAK_TEST_PASSWORD_GRANT is not set, skipping...
=== RUN   TestProvider
--- PASS: TestProvider (0.00s)
=== RUN   TestAccKeycloakAttributeImporterIdentityProviderMapper_basic
--- PASS: TestAccKeycloakAttributeImporterIdentityProviderMapper_basic (0.88s)
=== RUN   TestAccKeycloakAttributeImporterIdentityProviderMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakAttributeImporterIdentityProviderMapper_createAfterManualDestroy (1.11s)
=== RUN   TestAccKeycloakAttributeImporterIdentityProviderMapper_basicUpdateRealm
--- PASS: TestAccKeycloakAttributeImporterIdentityProviderMapper_basicUpdateRealm (1.75s)
=== RUN   TestAccKeycloakAttributeImporterIdentityProviderMapper_basicUpdateAll
--- PASS: TestAccKeycloakAttributeImporterIdentityProviderMapper_basicUpdateAll (0.91s)
=== RUN   TestAccKeycloakAttributeToRoleIdentityProviderMapper_basic
--- PASS: TestAccKeycloakAttributeToRoleIdentityProviderMapper_basic (0.86s)
=== RUN   TestAccKeycloakAttributeToRoleIdentityProviderMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakAttributeToRoleIdentityProviderMapper_createAfterManualDestroy (0.93s)
=== RUN   TestAccKeycloakAttributeToRoleIdentityProviderMapper_basicUpdateRealm
--- PASS: TestAccKeycloakAttributeToRoleIdentityProviderMapper_basicUpdateRealm (1.65s)
=== RUN   TestAccKeycloakAttributeToRoleIdentityProviderMapper_basicUpdateAll
--- PASS: TestAccKeycloakAttributeToRoleIdentityProviderMapper_basicUpdateAll (1.09s)
=== RUN   TestAccKeycloakCustomUserFederation_basic
--- FAIL: TestAccKeycloakCustomUserFederation_basic (0.66s)
    testing.go:568: Step 0 error: errors during apply:
        
        Error: custom user federation provider with id custom is not installed on the server
        
          on /tmp/tf-test221777542/main.tf line 6:
          (source code not available)
        
        
=== RUN   TestAccKeycloakCustomUserFederation_customConfig
--- FAIL: TestAccKeycloakCustomUserFederation_customConfig (0.75s)
    testing.go:568: Step 0 error: errors during apply:
        
        Error: custom user federation provider with id custom is not installed on the server
        
          on /tmp/tf-test275492264/main.tf line 6:
          (source code not available)
        
        
=== RUN   TestAccKeycloakCustomUserFederation_createAfterManualDestroy
--- FAIL: TestAccKeycloakCustomUserFederation_createAfterManualDestroy (0.69s)
    testing.go:568: Step 0 error: errors during apply:
        
        Error: custom user federation provider with id custom is not installed on the server
        
          on /tmp/tf-test958193946/main.tf line 6:
          (source code not available)
        
        
=== RUN   TestAccKeycloakCustomUserFederation_validation
--- PASS: TestAccKeycloakCustomUserFederation_validation (0.77s)
=== RUN   TestAccKeycloakDefaultGroups_basic
--- PASS: TestAccKeycloakDefaultGroups_basic (0.87s)
=== RUN   TestAccKeycloakDefaultGroups_import
--- PASS: TestAccKeycloakDefaultGroups_import (0.81s)
=== RUN   TestAccKeycloakDefaultGroups_updateInPlace
--- PASS: TestAccKeycloakDefaultGroups_updateInPlace (1.14s)
=== RUN   TestAccKeycloakGenericClientProtocolMapper_basicClient
--- PASS: TestAccKeycloakGenericClientProtocolMapper_basicClient (0.97s)
=== RUN   TestAccKeycloakGenericClientProtocolMapper_import
--- PASS: TestAccKeycloakGenericClientProtocolMapper_import (0.96s)
=== RUN   TestGenericClientProtocolMapper_update
--- PASS: TestGenericClientProtocolMapper_update (1.04s)
=== RUN   TestAccKeycloakGroupMemberships_basic
--- PASS: TestAccKeycloakGroupMemberships_basic (0.91s)
=== RUN   TestAccKeycloakGroupMemberships_updateGroupForceNew
--- PASS: TestAccKeycloakGroupMemberships_updateGroupForceNew (0.91s)
=== RUN   TestAccKeycloakGroupMemberships_updateInPlace
--- PASS: TestAccKeycloakGroupMemberships_updateInPlace (1.08s)
=== RUN   TestAccKeycloakGroupMemberships_userDoesNotExist
--- PASS: TestAccKeycloakGroupMemberships_userDoesNotExist (0.81s)
=== RUN   TestAccKeycloakGroupMemberships_authoritativeAdd
--- PASS: TestAccKeycloakGroupMemberships_authoritativeAdd (1.02s)
=== RUN   TestAccKeycloakGroupMemberships_authoritativeRemove
--- PASS: TestAccKeycloakGroupMemberships_authoritativeRemove (1.04s)
=== RUN   TestAccKeycloakGroupMemberships_noImportNeeded
--- PASS: TestAccKeycloakGroupMemberships_noImportNeeded (1.01s)
=== RUN   TestAccKeycloakGroupMemberships_validateLowercaseUsernames
--- PASS: TestAccKeycloakGroupMemberships_validateLowercaseUsernames (0.89s)
=== RUN   TestAccKeycloakGroupMemberships_createAfterManualDestroy
--- PASS: TestAccKeycloakGroupMemberships_createAfterManualDestroy (0.97s)
=== RUN   TestAccKeycloakGroupRoles_basic
--- PASS: TestAccKeycloakGroupRoles_basic (1.19s)
=== RUN   TestAccKeycloakGroupRoles_update
--- PASS: TestAccKeycloakGroupRoles_update (2.63s)
=== RUN   TestAccKeycloakGroup_basic
--- PASS: TestAccKeycloakGroup_basic (0.88s)
=== RUN   TestAccKeycloakGroup_createAfterManualDestroy
--- PASS: TestAccKeycloakGroup_createAfterManualDestroy (0.94s)
=== RUN   TestAccKeycloakGroup_updateGroupName
--- PASS: TestAccKeycloakGroup_updateGroupName (0.89s)
=== RUN   TestAccKeycloakGroup_updateRealm
--- PASS: TestAccKeycloakGroup_updateRealm (0.98s)
=== RUN   TestAccKeycloakGroup_nested
--- PASS: TestAccKeycloakGroup_nested (1.08s)
=== RUN   TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basic
--- PASS: TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basic (0.82s)
=== RUN   TestAccKeycloakHardcodedAttributeIdentityProviderMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakHardcodedAttributeIdentityProviderMapper_createAfterManualDestroy (0.97s)
=== RUN   TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basicUpdateRealm
--- PASS: TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basicUpdateRealm (1.91s)
=== RUN   TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basicUpdateAll
--- PASS: TestAccKeycloakHardcodedAttributeIdentityProviderMapper_basicUpdateAll (1.02s)
=== RUN   TestAccKeycloakHardcodedRoleIdentityProviderMapper_basic
--- PASS: TestAccKeycloakHardcodedRoleIdentityProviderMapper_basic (1.02s)
=== RUN   TestAccKeycloakHardcodedRoleIdentityProviderMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakHardcodedRoleIdentityProviderMapper_createAfterManualDestroy (1.05s)
=== RUN   TestAccKeycloakHardcodedRoleIdentityProviderMapper_basicUpdateRealm
--- PASS: TestAccKeycloakHardcodedRoleIdentityProviderMapper_basicUpdateRealm (1.98s)
=== RUN   TestAccKeycloakHardcodedRoleIdentityProviderMapper_basicUpdateAll
--- PASS: TestAccKeycloakHardcodedRoleIdentityProviderMapper_basicUpdateAll (1.14s)
=== RUN   TestAccKeycloakLdapFullNameMapper_basic
--- PASS: TestAccKeycloakLdapFullNameMapper_basic (0.98s)
=== RUN   TestAccKeycloakLdapFullNameMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakLdapFullNameMapper_createAfterManualDestroy (1.06s)
=== RUN   TestAccKeycloakLdapFullNameMapper_readWriteValidation
--- PASS: TestAccKeycloakLdapFullNameMapper_readWriteValidation (0.81s)
=== RUN   TestAccKeycloakLdapFullNameMapper_writableValidation
--- PASS: TestAccKeycloakLdapFullNameMapper_writableValidation (0.92s)
=== RUN   TestAccKeycloakLdapFullNameMapper_updateLdapUserFederation
--- PASS: TestAccKeycloakLdapFullNameMapper_updateLdapUserFederation (1.04s)
=== RUN   TestAccKeycloakLdapGroupMapper_basic
--- PASS: TestAccKeycloakLdapGroupMapper_basic (0.88s)
=== RUN   TestAccKeycloakLdapGroupMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakLdapGroupMapper_createAfterManualDestroy (0.98s)
=== RUN   TestAccKeycloakLdapGroupMapper_modeValidation
--- PASS: TestAccKeycloakLdapGroupMapper_modeValidation (1.06s)
=== RUN   TestAccKeycloakLdapGroupMapper_membershipAttributeTypeValidation
--- PASS: TestAccKeycloakLdapGroupMapper_membershipAttributeTypeValidation (0.92s)
=== RUN   TestAccKeycloakLdapGroupMapper_userRolesRetrieveStrategyValidation
--- PASS: TestAccKeycloakLdapGroupMapper_userRolesRetrieveStrategyValidation (0.94s)
=== RUN   TestAccKeycloakLdapGroupMapper_groupsLdapFilterValidation
--- PASS: TestAccKeycloakLdapGroupMapper_groupsLdapFilterValidation (0.84s)
=== RUN   TestAccKeycloakLdapGroupMapper_groupInheritanceValidation
--- PASS: TestAccKeycloakLdapGroupMapper_groupInheritanceValidation (0.87s)
=== RUN   TestAccKeycloakLdapGroupMapper_updateLdapUserFederationForceNew
--- PASS: TestAccKeycloakLdapGroupMapper_updateLdapUserFederationForceNew (1.02s)
=== RUN   TestAccKeycloakLdapGroupMapper_updateLdapUserFederationInPlace
--- PASS: TestAccKeycloakLdapGroupMapper_updateLdapUserFederationInPlace (1.02s)
=== RUN   TestAccKeycloakLdapMsadUserAccountControlMapper_basic
--- PASS: TestAccKeycloakLdapMsadUserAccountControlMapper_basic (0.93s)
=== RUN   TestAccKeycloakLdapMsadUserAccountControlMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakLdapMsadUserAccountControlMapper_createAfterManualDestroy (0.97s)
=== RUN   TestAccKeycloakLdapMsadUserAccountControlMapper_updateLdapUserFederation
--- PASS: TestAccKeycloakLdapMsadUserAccountControlMapper_updateLdapUserFederation (1.01s)
=== RUN   TestAccKeycloakLdapMsadUserAccountControlMapper_updateInPlace
--- PASS: TestAccKeycloakLdapMsadUserAccountControlMapper_updateInPlace (1.11s)
=== RUN   TestAccKeycloakLdapUserAttributeMapper_basic
--- PASS: TestAccKeycloakLdapUserAttributeMapper_basic (1.03s)
=== RUN   TestAccKeycloakLdapUserAttributeMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakLdapUserAttributeMapper_createAfterManualDestroy (1.05s)
=== RUN   TestAccKeycloakLdapUserAttributeMapper_updateLdapUserFederation
--- PASS: TestAccKeycloakLdapUserAttributeMapper_updateLdapUserFederation (1.02s)
=== RUN   TestAccKeycloakLdapUserAttributeMapper_updateInPlace
--- PASS: TestAccKeycloakLdapUserAttributeMapper_updateInPlace (1.09s)
=== RUN   TestAccKeycloakLdapUserFederation_basic
--- PASS: TestAccKeycloakLdapUserFederation_basic (0.81s)
=== RUN   TestAccKeycloakLdapUserFederation_import
--- PASS: TestAccKeycloakLdapUserFederation_import (1.02s)
=== RUN   TestAccKeycloakLdapUserFederation_createAfterManualDestroy
--- PASS: TestAccKeycloakLdapUserFederation_createAfterManualDestroy (0.93s)
=== RUN   TestAccKeycloakLdapUserFederation_basicUpdateRealm
--- PASS: TestAccKeycloakLdapUserFederation_basicUpdateRealm (1.66s)
=== RUN   TestAccKeycloakLdapUserFederation_basicUpdateAll
--- PASS: TestAccKeycloakLdapUserFederation_basicUpdateAll (0.96s)
=== RUN   TestAccKeycloakLdapUserFederation_unsetTimeoutDurationStrings
--- PASS: TestAccKeycloakLdapUserFederation_unsetTimeoutDurationStrings (1.13s)
=== RUN   TestAccKeycloakLdapUserFederation_editModeValidation
--- PASS: TestAccKeycloakLdapUserFederation_editModeValidation (0.87s)
=== RUN   TestAccKeycloakLdapUserFederation_vendorValidation
--- PASS: TestAccKeycloakLdapUserFederation_vendorValidation (0.84s)
=== RUN   TestAccKeycloakLdapUserFederation_searchScopeValidation
--- PASS: TestAccKeycloakLdapUserFederation_searchScopeValidation (0.87s)
=== RUN   TestAccKeycloakLdapUserFederation_useTrustStoreValidation
--- PASS: TestAccKeycloakLdapUserFederation_useTrustStoreValidation (0.82s)
=== RUN   TestAccKeycloakLdapUserFederation_cachePolicyValidation
--- PASS: TestAccKeycloakLdapUserFederation_cachePolicyValidation (0.85s)
=== RUN   TestAccKeycloakLdapUserFederation_bindValidation
--- PASS: TestAccKeycloakLdapUserFederation_bindValidation (0.75s)
=== RUN   TestAccKeycloakLdapUserFederation_syncPeriodValidation
--- PASS: TestAccKeycloakLdapUserFederation_syncPeriodValidation (0.91s)
=== RUN   TestAccKeycloakLdapUserFederation_bindCredential
--- PASS: TestAccKeycloakLdapUserFederation_bindCredential (0.91s)
=== RUN   TestAccKeycloakOidcIdentityProvider_basic
--- PASS: TestAccKeycloakOidcIdentityProvider_basic (0.84s)
=== RUN   TestAccKeycloakOidcIdentityProvider_custom
--- PASS: TestAccKeycloakOidcIdentityProvider_custom (0.83s)
=== RUN   TestAccKeycloakOidcIdentityProvider_createAfterManualDestroy
--- PASS: TestAccKeycloakOidcIdentityProvider_createAfterManualDestroy (0.91s)
=== RUN   TestAccKeycloakOidcIdentityProvider_basicUpdateRealm
--- PASS: TestAccKeycloakOidcIdentityProvider_basicUpdateRealm (1.77s)
=== RUN   TestAccKeycloakOidcIdentityProvider_basicUpdateAll
--- PASS: TestAccKeycloakOidcIdentityProvider_basicUpdateAll (1.19s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_basicClient
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_basicClient (0.73s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_basicClientScope
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_basicClientScope (0.84s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_import (0.94s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_update (0.90s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_createAfterManualDestroy (1.05s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_updateClientIdForceNew (1.17s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_updateClientScopeForceNew
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_updateClientScopeForceNew (0.91s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_updateRealmIdForceNew
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_updateRealmIdForceNew (1.61s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_validateClientConflictsWithClientScope
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_validateClientConflictsWithClientScope (0.91s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_validateClientAudienceConflictsWithCustomAudience
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_validateClientAudienceConflictsWithCustomAudience (0.72s)
=== RUN   TestAccKeycloakOpenIdAudienceProtocolMapper_validateClientAudienceExists
--- PASS: TestAccKeycloakOpenIdAudienceProtocolMapper_validateClientAudienceExists (0.66s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationPermission_basic
--- PASS: TestAccKeycloakOpenidClientAuthorizationPermission_basic (0.95s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationPermission_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenidClientAuthorizationPermission_createAfterManualDestroy (1.13s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationPermission_basicUpdateRealm
--- PASS: TestAccKeycloakOpenidClientAuthorizationPermission_basicUpdateRealm (1.88s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationPermission_basicUpdateAll
--- PASS: TestAccKeycloakOpenidClientAuthorizationPermission_basicUpdateAll (1.05s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationResource_basic
--- PASS: TestAccKeycloakOpenidClientAuthorizationResource_basic (0.81s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationResource_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenidClientAuthorizationResource_createAfterManualDestroy (1.01s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationResource_basicUpdateRealm
--- PASS: TestAccKeycloakOpenidClientAuthorizationResource_basicUpdateRealm (1.65s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationResource_basicUpdateAll
--- PASS: TestAccKeycloakOpenidClientAuthorizationResource_basicUpdateAll (1.11s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationScope_basic
--- PASS: TestAccKeycloakOpenidClientAuthorizationScope_basic (0.86s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationScope_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenidClientAuthorizationScope_createAfterManualDestroy (0.96s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationScope_basicUpdateRealm
--- PASS: TestAccKeycloakOpenidClientAuthorizationScope_basicUpdateRealm (1.66s)
=== RUN   TestAccKeycloakOpenidClientAuthorizationScope_basicUpdateAll
--- PASS: TestAccKeycloakOpenidClientAuthorizationScope_basicUpdateAll (0.88s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_basic
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_basic (1.06s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_updateClientForceNew
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_updateClientForceNew (0.98s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_updateInPlace
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_updateInPlace (1.07s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_validateClientDoesNotExist
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_validateClientDoesNotExist (0.85s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_validateClientAccessType
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_validateClientAccessType (0.93s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_authoritativeAdd
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_authoritativeAdd (1.15s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_authoritativeRemove
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_authoritativeRemove (1.08s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_noImportNeeded
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_noImportNeeded (0.99s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_profileAndEmailDefaultScopes
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_profileAndEmailDefaultScopes (0.98s)
=== RUN   TestAccKeycloakOpenidClientDefaultScopes_validateDuplicateScopeAssignment
--- PASS: TestAccKeycloakOpenidClientDefaultScopes_validateDuplicateScopeAssignment (0.92s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_basic
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_basic (1.15s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_updateClientForceNew
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_updateClientForceNew (0.97s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_updateInPlace
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_updateInPlace (1.14s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_validateClientDoesNotExist
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_validateClientDoesNotExist (0.92s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_validateClientAccessType
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_validateClientAccessType (0.77s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_authoritativeAdd
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_authoritativeAdd (1.24s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_authoritativeRemove
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_authoritativeRemove (1.33s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_noImportNeeded
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_noImportNeeded (1.08s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_profileAndEmailOptionalScopes
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_profileAndEmailOptionalScopes (0.91s)
=== RUN   TestAccKeycloakOpenidClientOptionalScopes_validateDuplicateScopeAssignment
--- PASS: TestAccKeycloakOpenidClientOptionalScopes_validateDuplicateScopeAssignment (0.96s)
=== RUN   TestAccKeycloakClientScope_basic
--- PASS: TestAccKeycloakClientScope_basic (1.10s)
=== RUN   TestAccKeycloakClientScope_createAfterManualDestroy
--- PASS: TestAccKeycloakClientScope_createAfterManualDestroy (0.89s)
=== RUN   TestAccKeycloakClientScope_updateRealm
--- PASS: TestAccKeycloakClientScope_updateRealm (1.04s)
=== RUN   TestAccKeycloakClientScope_consentScreenText
--- PASS: TestAccKeycloakClientScope_consentScreenText (1.00s)
=== RUN   TestAccKeycloakOpenidClientServiceAccountRole_basic
--- PASS: TestAccKeycloakOpenidClientServiceAccountRole_basic (0.92s)
=== RUN   TestAccKeycloakOpenidClientServiceAccountRole_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenidClientServiceAccountRole_createAfterManualDestroy (1.06s)
=== RUN   TestAccKeycloakOpenidClientServiceAccountRole_basicUpdateRealm
--- PASS: TestAccKeycloakOpenidClientServiceAccountRole_basicUpdateRealm (1.53s)
=== RUN   TestAccKeycloakOpenidClient_basic
--- PASS: TestAccKeycloakOpenidClient_basic (0.98s)
=== RUN   TestAccKeycloakOpenidClient_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenidClient_createAfterManualDestroy (1.04s)
=== RUN   TestAccKeycloakOpenidClient_updateRealm
--- PASS: TestAccKeycloakOpenidClient_updateRealm (1.03s)
=== RUN   TestAccKeycloakOpenidClient_accessType
--- PASS: TestAccKeycloakOpenidClient_accessType (1.00s)
=== RUN   TestAccKeycloakOpenidClient_updateInPlace
--- PASS: TestAccKeycloakOpenidClient_updateInPlace (1.00s)
=== RUN   TestAccKeycloakOpenidClient_secret
--- PASS: TestAccKeycloakOpenidClient_secret (0.83s)
=== RUN   TestAccKeycloakOpenidClient_redirectUrisValidation
--- PASS: TestAccKeycloakOpenidClient_redirectUrisValidation (0.72s)
=== RUN   TestAccKeycloakOpenidClient_publicClientCredentialsValidation
--- PASS: TestAccKeycloakOpenidClient_publicClientCredentialsValidation (0.66s)
=== RUN   TestAccKeycloakOpenidClient_bearerClientNoGrantsValidation
--- PASS: TestAccKeycloakOpenidClient_bearerClientNoGrantsValidation (0.76s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_basicClient
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_basicClient (0.93s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_basicClientScope
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_basicClientScope (0.82s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_import (0.93s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_update (0.97s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_createAfterManualDestroy (0.90s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_updateMapperNameForceNew
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_updateMapperNameForceNew (0.98s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_updateClientIdForceNew (0.88s)
=== RUN   TestAccKeycloakOpenIdFullNameProtocolMapper_updateClientScopeForceNew
--- PASS: TestAccKeycloakOpenIdFullNameProtocolMapper_updateClientScopeForceNew (0.93s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_basicClient
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_basicClient (0.79s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_basicClientScope
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_basicClientScope (1.00s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_import (0.90s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_update (0.94s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_createAfterManualDestroy (0.85s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_updateMapperNameForceNew
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_updateMapperNameForceNew (0.90s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_updateClientIdForceNew (0.91s)
=== RUN   TestAccKeycloakOpenIdGroupMembershipProtocolMapper_updateClientScopeForceNew
--- PASS: TestAccKeycloakOpenIdGroupMembershipProtocolMapper_updateClientScopeForceNew (0.91s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_basicClient
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_basicClient (0.94s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_basicClientScope
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_basicClientScope (0.87s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_import (0.85s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_update (0.96s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_createAfterManualDestroy (0.94s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_validateClaimValueType
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_validateClaimValueType (0.01s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_updateClientIdForceNew (0.88s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_updateClientScopeForceNew
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_updateClientScopeForceNew (0.94s)
=== RUN   TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_updateRealmIdForceNew
--- PASS: TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_updateRealmIdForceNew (1.46s)
=== RUN   TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_basicRealmRole_client
--- PASS: TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_basicRealmRole_client (0.77s)
=== RUN   TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_basicClientRole_client
--- FAIL: TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_basicClientRole_client (0.59s)
    testing.go:629: Error destroying resource! WARNING: Dangling resources
        may exist. The full state and error is shown below.
        
        Error: errors during apply: error sending DELETE request to /auth/admin/realms/terraform-realm-3tdtopzudo/roles-by-id/dcdc1349-2184-4c57-bc8f-ba94fc732d84: 500 Internal Server Error
        
        State: keycloak_openid_client.openid_client_for_role:
          ID = 0ea14bc5-217e-47d8-9be8-fe44eae62929
          provider = provider.keycloak
          access_type = BEARER-ONLY
          authorization.# = 0
          client_id = terraform-client-2adfxlss31
          client_secret = 2933da08-f834-4910-99a8-63f9cc916ee1
          description = 
          direct_access_grants_enabled = false
          enabled = true
          implicit_flow_enabled = false
          name = 
          realm_id = terraform-realm-3tdtopzudo
          service_accounts_enabled = false
          standard_flow_enabled = false
          valid_redirect_uris.# = 0
          web_origins.# = 0
        
          Dependencies:
            keycloak_realm.realm
        keycloak_realm.realm:
          ID = terraform-realm-3tdtopzudo
          provider = provider.keycloak
          access_code_lifespan = 1m0s
          access_code_lifespan_login = 30m0s
          access_code_lifespan_user_action = 5m0s
          access_token_lifespan = 5m0s
          access_token_lifespan_for_implicit_flow = 15m0s
          account_theme = 
          action_token_generated_by_admin_lifespan = 12h0m0s
          action_token_generated_by_user_lifespan = 5m0s
          admin_theme = 
          browser_flow = browser
          client_authentication_flow = clients
          direct_grant_flow = direct grant
          display_name = 
          docker_authentication_flow = docker auth
          duplicate_emails_allowed = false
          edit_username_allowed = false
          email_theme = 
          enabled = true
          internationalization.# = 0
          login_theme = 
          login_with_email_allowed = false
          offline_session_idle_timeout = 720h0m0s
          offline_session_max_lifespan = 1440h0m0s
          password_policy = 
          realm = terraform-realm-3tdtopzudo
          refresh_token_max_reuse = 0
          registration_allowed = false
          registration_email_as_username = false
          registration_flow = registration
          remember_me = false
          reset_credentials_flow = registration
          reset_password_allowed = false
          security_defenses.# = 0
          smtp_server.# = 0
          sso_session_idle_timeout = 30m0s
          sso_session_max_lifespan = 10h0m0s
          verify_email = false
        keycloak_role.role:
          ID = dcdc1349-2184-4c57-bc8f-ba94fc732d84
          provider = provider.keycloak
          client_id = 0ea14bc5-217e-47d8-9be8-fe44eae62929
          description = 
          name = terraform-role-vguaed01ce
          realm_id = terraform-realm-3tdtopzudo
=== RUN   TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_basicRealmRole_clientScope
--- PASS: TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_basicRealmRole_clientScope (1.00s)
=== RUN   TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_import (0.92s)
=== RUN   TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_update (1.11s)
=== RUN   TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdHardcodedRoleProtocolMapper_createAfterManualDestroy (0.95s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_basicClient
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_basicClient (0.81s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_basicClientScope
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_basicClientScope (1.00s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_import (1.20s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_update (1.00s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_createAfterManualDestroy (1.03s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_validateClaimValueType
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_validateClaimValueType (0.01s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_updateClientIdForceNew (0.99s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_updateClientScopeForceNew
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_updateClientScopeForceNew (0.90s)
=== RUN   TestAccKeycloakOpenIdUserAttributeProtocolMapper_updateRealmIdForceNew
--- PASS: TestAccKeycloakOpenIdUserAttributeProtocolMapper_updateRealmIdForceNew (1.59s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_basicClient
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_basicClient (0.76s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_basicClientScope
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_basicClientScope (0.74s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_import (0.83s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_update (0.91s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_createAfterManualDestroy (1.08s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_validateClaimValueType
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_validateClaimValueType (0.01s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_updateClientIdForceNew (0.95s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_updateClientScopeForceNew
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_updateClientScopeForceNew (1.06s)
=== RUN   TestAccKeycloakOpenIdUserPropertyProtocolMapper_updateRealmIdForceNew
--- PASS: TestAccKeycloakOpenIdUserPropertyProtocolMapper_updateRealmIdForceNew (2.25s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_basicClient
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_basicClient (0.98s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_basicClientScope
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_basicClientScope (0.97s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_import
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_import (0.91s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_update
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_update (0.90s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_createAfterManualDestroy (1.13s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_validateClaimValueType
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_validateClaimValueType (0.01s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateClientIdForceNew (0.91s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateClientScopeForceNew
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateClientScopeForceNew (0.92s)
=== RUN   TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateRealmIdForceNew
--- PASS: TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateRealmIdForceNew (1.83s)
=== RUN   TestAccKeycloakRealm_basic
--- PASS: TestAccKeycloakRealm_basic (1.02s)
=== RUN   TestAccKeycloakRealm_createAfterManualDestroy
--- PASS: TestAccKeycloakRealm_createAfterManualDestroy (1.73s)
=== RUN   TestAccKeycloakRealm_import
--- PASS: TestAccKeycloakRealm_import (0.83s)
=== RUN   TestAccKeycloakRealm_SmtpServer
--- PASS: TestAccKeycloakRealm_SmtpServer (0.82s)
=== RUN   TestAccKeycloakRealm_SmtpServerUpdate
--- PASS: TestAccKeycloakRealm_SmtpServerUpdate (0.87s)
=== RUN   TestAccKeycloakRealm_SmtpServerInvalid
--- PASS: TestAccKeycloakRealm_SmtpServerInvalid (0.02s)
=== RUN   TestAccKeycloakRealm_themes
--- PASS: TestAccKeycloakRealm_themes (1.18s)
=== RUN   TestAccKeycloakRealm_themesValidation
--- PASS: TestAccKeycloakRealm_themesValidation (0.19s)
=== RUN   TestAccKeycloakRealm_InternationalizationValidation
--- PASS: TestAccKeycloakRealm_InternationalizationValidation (0.08s)
=== RUN   TestAccKeycloakRealm_Internationalization
--- PASS: TestAccKeycloakRealm_Internationalization (1.05s)
=== RUN   TestAccKeycloakRealm_InternationalizationDisabled
--- PASS: TestAccKeycloakRealm_InternationalizationDisabled (0.69s)
=== RUN   TestAccKeycloakRealm_loginConfigBasic
--- PASS: TestAccKeycloakRealm_loginConfigBasic (0.77s)
=== RUN   TestAccKeycloakRealm_loginConfigValidation
--- PASS: TestAccKeycloakRealm_loginConfigValidation (0.13s)
=== RUN   TestAccKeycloakRealm_tokenSettings
--- PASS: TestAccKeycloakRealm_tokenSettings (0.95s)
=== RUN   TestAccKeycloakRealm_computedTokenSettings
--- PASS: TestAccKeycloakRealm_computedTokenSettings (0.74s)
=== RUN   TestAccKeycloakRealm_securityDefenses
--- PASS: TestAccKeycloakRealm_securityDefenses (1.20s)
=== RUN   TestAccKeycloakRealm_passwordPolicy
--- PASS: TestAccKeycloakRealm_passwordPolicy (1.15s)
=== RUN   TestAccKeycloakRealm_browserFlow
--- PASS: TestAccKeycloakRealm_browserFlow (1.05s)
=== RUN   TestAccKeycloakRealm_passwordPolicyInvalid
--- PASS: TestAccKeycloakRealm_passwordPolicyInvalid (0.88s)
=== RUN   TestAccKeycloakRequiredAction_basic
--- PASS: TestAccKeycloakRequiredAction_basic (1.03s)
=== RUN   TestAccKeycloakRequiredAction_invalidAlias
--- PASS: TestAccKeycloakRequiredAction_invalidAlias (0.74s)
=== RUN   TestAccKeycloakRequiredAction_import
--- PASS: TestAccKeycloakRequiredAction_import (1.05s)
=== RUN   TestAccKeycloakRequiredAction_disabledDefault
--- PASS: TestAccKeycloakRequiredAction_disabledDefault (1.08s)
=== RUN   TestAccKeycloakRequiredAction_computedPriority
--- PASS: TestAccKeycloakRequiredAction_computedPriority (1.21s)
=== RUN   TestAccKeycloakRole_basicRealm
--- PASS: TestAccKeycloakRole_basicRealm (1.05s)
=== RUN   TestAccKeycloakRole_basicClient
--- PASS: TestAccKeycloakRole_basicClient (1.03s)
=== RUN   TestAccKeycloakRole_basicSamlClient
--- PASS: TestAccKeycloakRole_basicSamlClient (0.87s)
=== RUN   TestAccKeycloakRole_basicRealmUpdate
--- PASS: TestAccKeycloakRole_basicRealmUpdate (1.18s)
=== RUN   TestAccKeycloakRole_basicClientUpdate
--- PASS: TestAccKeycloakRole_basicClientUpdate (1.37s)
=== RUN   TestAccKeycloakRole_createAfterManualDestroy
--- PASS: TestAccKeycloakRole_createAfterManualDestroy (0.84s)
=== RUN   TestAccKeycloakRole_composites
--- PASS: TestAccKeycloakRole_composites (1.49s)
=== RUN   TestAccKeycloakSamlClient_basic
--- PASS: TestAccKeycloakSamlClient_basic (0.98s)
=== RUN   TestAccKeycloakSamlClient_createAfterManualDestroy
--- PASS: TestAccKeycloakSamlClient_createAfterManualDestroy (1.13s)
=== RUN   TestAccKeycloakSamlClient_updateRealm
--- PASS: TestAccKeycloakSamlClient_updateRealm (1.24s)
=== RUN   TestAccKeycloakSamlClient_keycloakDefaults
--- PASS: TestAccKeycloakSamlClient_keycloakDefaults (0.85s)
=== RUN   TestAccKeycloakSamlClient_updateInPlace
--- PASS: TestAccKeycloakSamlClient_updateInPlace (1.03s)
=== RUN   TestAccKeycloakSamlClient_certificateAndKey
--- PASS: TestAccKeycloakSamlClient_certificateAndKey (0.94s)
=== RUN   TestAccKeycloakSamlIdentityProvider_basic
--- PASS: TestAccKeycloakSamlIdentityProvider_basic (1.01s)
=== RUN   TestAccKeycloakSamlIdentityProvider_createAfterManualDestroy
--- PASS: TestAccKeycloakSamlIdentityProvider_createAfterManualDestroy (1.06s)
=== RUN   TestAccKeycloakSamlIdentityProvider_basicUpdateRealm
--- PASS: TestAccKeycloakSamlIdentityProvider_basicUpdateRealm (1.88s)
=== RUN   TestAccKeycloakSamlIdentityProvider_basicUpdateAll
--- PASS: TestAccKeycloakSamlIdentityProvider_basicUpdateAll (0.95s)
=== RUN   TestAccKeycloakSamlUserAttributeProtocolMapper_basicClient
--- PASS: TestAccKeycloakSamlUserAttributeProtocolMapper_basicClient (0.95s)
=== RUN   TestAccKeycloakSamlUserAttributeProtocolMapper_import
--- PASS: TestAccKeycloakSamlUserAttributeProtocolMapper_import (0.85s)
=== RUN   TestAccKeycloakSamlUserAttributeProtocolMapper_update
--- PASS: TestAccKeycloakSamlUserAttributeProtocolMapper_update (0.99s)
=== RUN   TestAccKeycloakSamlUserAttributeProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakSamlUserAttributeProtocolMapper_createAfterManualDestroy (1.05s)
=== RUN   TestAccKeycloakSamlUserAttributeProtocolMapper_validateClaimValueType
--- PASS: TestAccKeycloakSamlUserAttributeProtocolMapper_validateClaimValueType (0.01s)
=== RUN   TestAccKeycloakSamlUserAttributeProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakSamlUserAttributeProtocolMapper_updateClientIdForceNew (1.26s)
=== RUN   TestAccKeycloakSamlUserAttributeProtocolMapper_updateRealmIdForceNew
--- PASS: TestAccKeycloakSamlUserAttributeProtocolMapper_updateRealmIdForceNew (1.66s)
=== RUN   TestAccKeycloakSamlUserPropertyProtocolMapper_basicClient
--- PASS: TestAccKeycloakSamlUserPropertyProtocolMapper_basicClient (0.89s)
=== RUN   TestAccKeycloakSamlUserPropertyProtocolMapper_import
--- PASS: TestAccKeycloakSamlUserPropertyProtocolMapper_import (0.81s)
=== RUN   TestAccKeycloakSamlUserPropertyProtocolMapper_update
--- PASS: TestAccKeycloakSamlUserPropertyProtocolMapper_update (0.84s)
=== RUN   TestAccKeycloakSamlUserPropertyProtocolMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakSamlUserPropertyProtocolMapper_createAfterManualDestroy (1.29s)
=== RUN   TestAccKeycloakSamlUserPropertyProtocolMapper_validateClaimValueType
--- PASS: TestAccKeycloakSamlUserPropertyProtocolMapper_validateClaimValueType (0.01s)
=== RUN   TestAccKeycloakSamlUserPropertyProtocolMapper_updateClientIdForceNew
--- PASS: TestAccKeycloakSamlUserPropertyProtocolMapper_updateClientIdForceNew (1.07s)
=== RUN   TestAccKeycloakSamlUserPropertyProtocolMapper_updateRealmIdForceNew
--- PASS: TestAccKeycloakSamlUserPropertyProtocolMapper_updateRealmIdForceNew (2.47s)
=== RUN   TestAccKeycloakUserTemplateIdentityProviderMapper_basic
--- PASS: TestAccKeycloakUserTemplateIdentityProviderMapper_basic (1.01s)
=== RUN   TestAccKeycloakUserTemplateIdentityProviderMapper_createAfterManualDestroy
--- PASS: TestAccKeycloakUserTemplateIdentityProviderMapper_createAfterManualDestroy (1.30s)
=== RUN   TestAccKeycloakUserTemplateIdentityProviderMapper_basicUpdateRealm
--- PASS: TestAccKeycloakUserTemplateIdentityProviderMapper_basicUpdateRealm (1.93s)
=== RUN   TestAccKeycloakUserTemplateIdentityProviderMapper_basicUpdateAll
--- PASS: TestAccKeycloakUserTemplateIdentityProviderMapper_basicUpdateAll (1.11s)
=== RUN   TestAccKeycloakUser_basic
--- PASS: TestAccKeycloakUser_basic (0.84s)
=== RUN   TestAccKeycloakUser_withInitialPassword
--- PASS: TestAccKeycloakUser_withInitialPassword (1.10s)
=== RUN   TestAccKeycloakUser_createAfterManualDestroy
--- PASS: TestAccKeycloakUser_createAfterManualDestroy (0.84s)
=== RUN   TestAccKeycloakUser_updateRealm
--- PASS: TestAccKeycloakUser_updateRealm (1.13s)
=== RUN   TestAccKeycloakUser_updateUsername
--- PASS: TestAccKeycloakUser_updateUsername (0.97s)
=== RUN   TestAccKeycloakUser_updateWithInitialPasswordChangeDoesNotReset
--- PASS: TestAccKeycloakUser_updateWithInitialPasswordChangeDoesNotReset (1.12s)
=== RUN   TestAccKeycloakUser_updateInPlace
--- PASS: TestAccKeycloakUser_updateInPlace (1.00s)
=== RUN   TestAccKeycloakUser_unsetOptionalAttributes
--- PASS: TestAccKeycloakUser_unsetOptionalAttributes (0.95s)
=== RUN   TestAccKeycloakUser_validateLowercaseUsernames
--- PASS: TestAccKeycloakUser_validateLowercaseUsernames (0.01s)
```

mrparkers: Yeah the `roles-by-id` endpoint has been unhappy lately during tests.  I'm thinking I probably have a race condition in some of those tests that use roles that makes them fail more frequently than I'd like.

Anyways, this looks good, thanks for the PR!

Patch:
diff --git a/docs/resources/keycloak_openid_user_realm_role_protocol_mapper.md b/docs/resources/keycloak_openid_user_realm_role_protocol_mapper.md
new file mode 100644
index 0000000..e1df531
--- /dev/null
+++ b/docs/resources/keycloak_openid_user_realm_role_protocol_mapper.md
@@ -0,0 +1,90 @@
+# keycloak_openid_user_realm_role_protocol_mapper
+
+Allows for creating and managing user realm role protocol mappers within
+Keycloak.
+
+User realm role protocol mappers allow you to define a claim containing the list of the realm roles.
+Protocol mappers can be defined for a single client, or they can
+be defined for a client scope which can be shared between multiple different
+clients.
+
+### Example Usage (Client)
+
+```hcl
+resource "keycloak_realm" "realm" {
+    realm   = "my-realm"
+    enabled = true
+}
+
+resource "keycloak_openid_client" "openid_client" {
+    realm_id            = "${keycloak_realm.realm.id}"
+    client_id           = "test-client"
+
+    name                = "test client"
+    enabled             = true
+
+    access_type         = "CONFIDENTIAL"
+    valid_redirect_uris = [
+        "http://localhost:8080/openid-callback"
+    ]
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper" {
+    realm_id    = "${keycloak_realm.realm.id}"
+    client_id   = "${keycloak_openid_client.openid_client.id}"
+    name        = "user-realm-role-mapper"
+
+    claim_name  = "foo"
+}
+```
+
+### Example Usage (Client Scope)
+
+```hcl
+resource "keycloak_realm" "realm" {
+    realm   = "my-realm"
+    enabled = true
+}
+
+resource "keycloak_openid_client_scope" "client_scope" {
+    realm_id = "${keycloak_realm.realm.id}"
+    name     = "test-client-scope"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper" {
+    realm_id        = "${keycloak_realm.realm.id}"
+    client_scope_id = "${keycloak_openid_client_scope.client_scope.id}"
+    name            = "user-realm-role-mapper"
+
+    claim_name      = "foo"
+}
+```
+
+### Argument Reference
+
+The following arguments are supported:
+
+- `realm_id` - (Required) The realm this protocol mapper exists within.
+- `client_id` - (Required if `client_scope_id` is not specified) The client this protocol mapper is attached to.
+- `client_scope_id` - (Required if `client_id` is not specified) The client scope this protocol mapper is attached to.
+- `name` - (Required) The display name of this protocol mapper in the GUI.
+- `claim_name` - (Required) The name of the claim to insert into a token.
+- `claim_value_type` - (Optional) The claim type used when serializing JSON tokens. Can be one of `String`, `long`, `int`, or `boolean`. Defaults to `String`.
+- `multivalued` - (Optional) Indicates if attribute supports multiple values. If true, then the list of all values of this attribute will be set as claim. If false, then just first value will be set as claim. Defaults to `true`.
+- `realm_role_prefix` - (Optional) A prefix for each Realm Role.
+- `add_to_id_token` - (Optional) Indicates if the property should be added as a claim to the id token. Defaults to `true`.
+- `add_to_access_token` - (Optional) Indicates if the property should be added as a claim to the access token. Defaults to `true`.
+- `add_to_userinfo` - (Optional) Indicates if the property should be added as a claim to the UserInfo response body. Defaults to `true`.
+
+### Import
+
+Protocol mappers can be imported using one of the following formats:
+- Client: `{{realm_id}}/client/{{client_keycloak_id}}/{{protocol_mapper_id}}`
+- Client Scope: `{{realm_id}}/client-scope/{{client_scope_keycloak_id}}/{{protocol_mapper_id}}`
+
+Example:
+
+```bash
+$ terraform import keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper my-realm/client/a7202154-8793-4656-b655-1dd18c181e14/71602afa-f7d1-4788-8c49-ef8fd00af0f4
+$ terraform import keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper my-realm/client-scope/b799ea7e-73ee-4a73-990a-1eafebe8e20a/71602afa-f7d1-4788-8c49-ef8fd00af0f4
+```
diff --git a/example/main.tf b/example/main.tf
index e24bc6c..e8df7ef 100644
--- a/example/main.tf
+++ b/example/main.tf
@@ -355,6 +355,22 @@ resource "keycloak_openid_hardcoded_claim_protocol_mapper" "hardcoded_claim_clie
   claim_value = "bar"
 }
 
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_client" {
+  name      = "tf-test-open-id-user-realm-role-claim-protocol-mapper-client"
+  realm_id  = "${keycloak_realm.test.id}"
+  client_id = "${keycloak_openid_client.test_client.id}"
+
+  claim_name  = "foo"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_client_scope" {
+  name            = "tf-test-open-id-user-realm-role-protocol-mapper-client-scope"
+  realm_id        = "${keycloak_realm.test.id}"
+  client_scope_id = "${keycloak_openid_client_scope.test_default_client_scope.id}"
+
+  claim_name  = "foo"
+}
+
 resource "keycloak_openid_client" "bearer_only_client" {
   client_id   = "test-bearer-only-client"
   name        = "test-bearer-only-client"
diff --git a/keycloak/openid_user_realm_role_protocol_mapper.go b/keycloak/openid_user_realm_role_protocol_mapper.go
new file mode 100644
index 0000000..20faaef
--- /dev/null
+++ b/keycloak/openid_user_realm_role_protocol_mapper.go
@@ -0,0 +1,133 @@
+package keycloak
+
+import (
+	"fmt"
+	"strconv"
+)
+
+type OpenIdUserRealmRoleProtocolMapper struct {
+	Id            string
+	Name          string
+	RealmId       string
+	ClientId      string
+	ClientScopeId string
+
+	AddToIdToken     bool
+	AddToAccessToken bool
+	AddToUserInfo    bool
+
+	RealmRolePrefix string
+	Multivalued     bool
+	ClaimName       string
+	ClaimValueType  string
+}
+
+func (mapper *OpenIdUserRealmRoleProtocolMapper) convertToGenericProtocolMapper() *protocolMapper {
+	return &protocolMapper{
+		Id:             mapper.Id,
+		Name:           mapper.Name,
+		Protocol:       "openid-connect",
+		ProtocolMapper: "oidc-usermodel-realm-role-mapper",
+		Config: map[string]string{
+			addToIdTokenField:                   strconv.FormatBool(mapper.AddToIdToken),
+			addToAccessTokenField:               strconv.FormatBool(mapper.AddToAccessToken),
+			addToUserInfoField:                  strconv.FormatBool(mapper.AddToUserInfo),
+			claimNameField:                      mapper.ClaimName,
+			claimValueTypeField:                 mapper.ClaimValueType,
+			multivaluedField:                    strconv.FormatBool(mapper.Multivalued),
+			userRealmRoleMappingRolePrefixField: mapper.RealmRolePrefix,
+		},
+	}
+}
+
+func (protocolMapper *protocolMapper) convertToOpenIdUserRealmRoleProtocolMapper(realmId, clientId, clientScopeId string) (*OpenIdUserRealmRoleProtocolMapper, error) {
+	addToIdToken, err := strconv.ParseBool(protocolMapper.Config[addToIdTokenField])
+	if err != nil {
+		return nil, err
+	}
+
+	addToAccessToken, err := strconv.ParseBool(protocolMapper.Config[addToAccessTokenField])
+	if err != nil {
+		return nil, err
+	}
+
+	addToUserInfo, err := strconv.ParseBool(protocolMapper.Config[addToUserInfoField])
+	if err != nil {
+		return nil, err
+	}
+
+	multivalued, err := strconv.ParseBool(protocolMapper.Config[multivaluedField])
+	if err != nil {
+		return nil, err
+	}
+
+	return &OpenIdUserRealmRoleProtocolMapper{
+		Id:            protocolMapper.Id,
+		Name:          protocolMapper.Name,
+		RealmId:       realmId,
+		ClientId:      clientId,
+		ClientScopeId: clientScopeId,
+
+		AddToIdToken:     addToIdToken,
+		AddToAccessToken: addToAccessToken,
+		AddToUserInfo:    addToUserInfo,
+
+		ClaimName:       protocolMapper.Config[claimNameField],
+		ClaimValueType:  protocolMapper.Config[claimValueTypeField],
+		Multivalued:     multivalued,
+		RealmRolePrefix: protocolMapper.Config[userRealmRoleMappingRolePrefixField],
+	}, nil
+}
+
+func (keycloakClient *KeycloakClient) GetOpenIdUserRealmRoleProtocolMapper(realmId, clientId, clientScopeId, mapperId string) (*OpenIdUserRealmRoleProtocolMapper, error) {
+	var protocolMapper *protocolMapper
+
+	err := keycloakClient.get(individualProtocolMapperPath(realmId, clientId, clientScopeId, mapperId), &protocolMapper, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return protocolMapper.convertToOpenIdUserRealmRoleProtocolMapper(realmId, clientId, clientScopeId)
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenIdUserRealmRoleProtocolMapper(realmId, clientId, clientScopeId, mapperId string) error {
+	return keycloakClient.delete(individualProtocolMapperPath(realmId, clientId, clientScopeId, mapperId), nil)
+}
+
+func (keycloakClient *KeycloakClient) NewOpenIdUserRealmRoleProtocolMapper(mapper *OpenIdUserRealmRoleProtocolMapper) error {
+	path := protocolMapperPath(mapper.RealmId, mapper.ClientId, mapper.ClientScopeId)
+
+	_, location, err := keycloakClient.post(path, mapper.convertToGenericProtocolMapper())
+	if err != nil {
+		return err
+	}
+
+	mapper.Id = getIdFromLocationHeader(location)
+
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenIdUserRealmRoleProtocolMapper(mapper *OpenIdUserRealmRoleProtocolMapper) error {
+	path := individualProtocolMapperPath(mapper.RealmId, mapper.ClientId, mapper.ClientScopeId, mapper.Id)
+
+	return keycloakClient.put(path, mapper.convertToGenericProtocolMapper())
+}
+
+func (keycloakClient *KeycloakClient) ValidateOpenIdUserRealmRoleProtocolMapper(mapper *OpenIdUserRealmRoleProtocolMapper) error {
+	if mapper.ClientId == "" && mapper.ClientScopeId == "" {
+		return fmt.Errorf("validation error: one of ClientId or ClientScopeId must be set")
+	}
+
+	protocolMappers, err := keycloakClient.listGenericProtocolMappers(mapper.RealmId, mapper.ClientId, mapper.ClientScopeId)
+	if err != nil {
+		return err
+	}
+
+	for _, protocolMapper := range protocolMappers {
+		if protocolMapper.Name == mapper.Name && protocolMapper.Id != mapper.Id {
+			return fmt.Errorf("validation error: a protocol mapper with name %s already exists for this client", mapper.Name)
+		}
+	}
+
+	return nil
+}
diff --git a/keycloak/protocol_mapper.go b/keycloak/protocol_mapper.go
index 92693e1..a72d57e 100644
--- a/keycloak/protocol_mapper.go
+++ b/keycloak/protocol_mapper.go
@@ -12,21 +12,22 @@ type protocolMapper struct {
 }
 
 var (
-	addToAccessTokenField       = "access.token.claim"
-	addToIdTokenField           = "id.token.claim"
-	addToUserInfoField          = "userinfo.token.claim"
-	attributeNameField          = "attribute.name"
-	attributeNameFormatField    = "attribute.nameformat"
-	claimNameField              = "claim.name"
-	claimValueField             = "claim.value"
-	claimValueTypeField         = "jsonType.label"
-	friendlyNameField           = "friendly.name"
-	fullPathField               = "full.path"
-	includedClientAudienceField = "included.client.audience"
-	includedCustomAudienceField = "included.custom.audience"
-	multivaluedField            = "multivalued"
-	userAttributeField          = "user.attribute"
-	userPropertyField           = "user.attribute"
+	addToAccessTokenField               = "access.token.claim"
+	addToIdTokenField                   = "id.token.claim"
+	addToUserInfoField                  = "userinfo.token.claim"
+	attributeNameField                  = "attribute.name"
+	attributeNameFormatField            = "attribute.nameformat"
+	claimNameField                      = "claim.name"
+	claimValueField                     = "claim.value"
+	claimValueTypeField                 = "jsonType.label"
+	friendlyNameField                   = "friendly.name"
+	fullPathField                       = "full.path"
+	includedClientAudienceField         = "included.client.audience"
+	includedCustomAudienceField         = "included.custom.audience"
+	multivaluedField                    = "multivalued"
+	userAttributeField                  = "user.attribute"
+	userPropertyField                   = "user.attribute"
+	userRealmRoleMappingRolePrefixField = "usermodel.realmRoleMapping.rolePrefix"
 )
 
 func protocolMapperPath(realmId, clientId, clientScopeId string) string {
diff --git a/mkdocs.yml b/mkdocs.yml
index 7433ada..ba7350a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -25,6 +25,7 @@ nav:
   - keycloak_openid_full_name_protocol_mapper: resources/keycloak_openid_full_name_protocol_mapper.md
   - keycloak_openid_audience_protocol_mapper: resources/keycloak_openid_audience_protocol_mapper.md
   - keycloak_openid_hardcoded_role_protocol_mapper: resources/keycloak_openid_hardcoded_role_protocol_mapper.md
+  - keycloak_openid_user_realm_role_protocol_mapper: resources/keycloak_openid_user_realm_role_protocol_mapper.md
   - keycloak_saml_client: resources/keycloak_saml_client.md
   - keycloak_saml_user_attribute_protocol_mapper: resources/keycloak_saml_user_attribute_protocol_mapper.md
   - keycloak_saml_user_property_protocol_mapper: resources/keycloak_saml_user_property_protocol_mapper.md
diff --git a/provider/provider.go b/provider/provider.go
index 7355a5b..06aa3b1 100644
--- a/provider/provider.go
+++ b/provider/provider.go
@@ -36,6 +36,7 @@ func KeycloakProvider() *schema.Provider {
 			"keycloak_openid_hardcoded_claim_protocol_mapper":          resourceKeycloakOpenIdHardcodedClaimProtocolMapper(),
 			"keycloak_openid_audience_protocol_mapper":                 resourceKeycloakOpenIdAudienceProtocolMapper(),
 			"keycloak_openid_hardcoded_role_protocol_mapper":           resourceKeycloakOpenIdHardcodedRoleProtocolMapper(),
+			"keycloak_openid_user_realm_role_protocol_mapper":          resourceKeycloakOpenIdUserRealmRoleProtocolMapper(),
 			"keycloak_openid_client_default_scopes":                    resourceKeycloakOpenidClientDefaultScopes(),
 			"keycloak_openid_client_optional_scopes":                   resourceKeycloakOpenidClientOptionalScopes(),
 			"keycloak_saml_client":                                     resourceKeycloakSamlClient(),
diff --git a/provider/resource_keycloak_openid_user_realm_role_protocol_mapper.go b/provider/resource_keycloak_openid_user_realm_role_protocol_mapper.go
new file mode 100644
index 0000000..54ea357
--- /dev/null
+++ b/provider/resource_keycloak_openid_user_realm_role_protocol_mapper.go
@@ -0,0 +1,192 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform/helper/schema"
+	"github.com/hashicorp/terraform/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenIdUserRealmRoleProtocolMapper() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenIdUserRealmRoleProtocolMapperCreate,
+		Read:   resourceKeycloakOpenIdUserRealmRoleProtocolMapperRead,
+		Update: resourceKeycloakOpenIdUserRealmRoleProtocolMapperUpdate,
+		Delete: resourceKeycloakOpenIdUserRealmRoleProtocolMapperDelete,
+		Importer: &schema.ResourceImporter{
+			// import a mapper tied to a client:
+			// {{realmId}}/client/{{clientId}}/{{protocolMapperId}}
+			// or a client scope:
+			// {{realmId}}/client-scope/{{clientScopeId}}/{{protocolMapperId}}
+			State: genericProtocolMapperImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:        schema.TypeString,
+				Required:    true,
+				Description: "A human-friendly name that will appear in the Keycloak console.",
+			},
+			"realm_id": {
+				Type:        schema.TypeString,
+				Required:    true,
+				ForceNew:    true,
+				Description: "The realm id where the associated client or client scope exists.",
+			},
+			"client_id": {
+				Type:          schema.TypeString,
+				Optional:      true,
+				ForceNew:      true,
+				Description:   "The mapper's associated client. Cannot be used at the same time as client_scope_id.",
+				ConflictsWith: []string{"client_scope_id"},
+			},
+			"client_scope_id": {
+				Type:          schema.TypeString,
+				Optional:      true,
+				ForceNew:      true,
+				Description:   "The mapper's associated client scope. Cannot be used at the same time as client_id.",
+				ConflictsWith: []string{"client_id"},
+			},
+			"add_to_id_token": {
+				Type:        schema.TypeBool,
+				Optional:    true,
+				Default:     true,
+				Description: "Indicates if the attribute should be a claim in the id token.",
+			},
+			"add_to_access_token": {
+				Type:        schema.TypeBool,
+				Optional:    true,
+				Default:     true,
+				Description: "Indicates if the attribute should be a claim in the access token.",
+			},
+			"add_to_userinfo": {
+				Type:        schema.TypeBool,
+				Optional:    true,
+				Default:     true,
+				Description: "Indicates if the attribute should appear in the userinfo response body.",
+			},
+			"claim_name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"claim_value_type": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				Description:  "Claim type used when serializing tokens.",
+				Default:      "String",
+				ValidateFunc: validation.StringInSlice([]string{"String", "long", "int", "boolean"}, true),
+			},
+			"multivalued": {
+				Type:        schema.TypeBool,
+				Optional:    true,
+				Default:     false,
+				Description: "Indicates whether this attribute is a single value or an array of values.",
+			},
+			"realm_role_prefix": {
+				Type:        schema.TypeString,
+				Optional:    true,
+				Description: "Prefix that will be added to each realm role.",
+			},
+		},
+	}
+}
+
+func mapFromDataToOpenIdUserRealmRoleProtocolMapper(data *schema.ResourceData) *keycloak.OpenIdUserRealmRoleProtocolMapper {
+	return &keycloak.OpenIdUserRealmRoleProtocolMapper{
+		Id:               data.Id(),
+		Name:             data.Get("name").(string),
+		RealmId:          data.Get("realm_id").(string),
+		ClientId:         data.Get("client_id").(string),
+		ClientScopeId:    data.Get("client_scope_id").(string),
+		AddToIdToken:     data.Get("add_to_id_token").(bool),
+		AddToAccessToken: data.Get("add_to_access_token").(bool),
+		AddToUserInfo:    data.Get("add_to_userinfo").(bool),
+
+		ClaimName:       data.Get("claim_name").(string),
+		ClaimValueType:  data.Get("claim_value_type").(string),
+		RealmRolePrefix: data.Get("realm_role_prefix").(string),
+		Multivalued:     data.Get("multivalued").(bool),
+	}
+}
+
+func mapFromOpenIdUserRealmRoleMapperToData(mapper *keycloak.OpenIdUserRealmRoleProtocolMapper, data *schema.ResourceData) {
+	data.SetId(mapper.Id)
+	data.Set("name", mapper.Name)
+	data.Set("realm_id", mapper.RealmId)
+
+	if mapper.ClientId != "" {
+		data.Set("client_id", mapper.ClientId)
+	} else {
+		data.Set("client_scope_id", mapper.ClientScopeId)
+	}
+
+	data.Set("add_to_id_token", mapper.AddToIdToken)
+	data.Set("add_to_access_token", mapper.AddToAccessToken)
+	data.Set("add_to_userinfo", mapper.AddToUserInfo)
+	data.Set("claim_name", mapper.ClaimName)
+	data.Set("claim_value_type", mapper.ClaimValueType)
+	data.Set("realm_role_prefix", mapper.RealmRolePrefix)
+	data.Set("multivalued", mapper.Multivalued)
+}
+
+func resourceKeycloakOpenIdUserRealmRoleProtocolMapperCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	openIdUserRealmRoleMapper := mapFromDataToOpenIdUserRealmRoleProtocolMapper(data)
+
+	err := keycloakClient.ValidateOpenIdUserRealmRoleProtocolMapper(openIdUserRealmRoleMapper)
+	if err != nil {
+		return err
+	}
+
+	err = keycloakClient.NewOpenIdUserRealmRoleProtocolMapper(openIdUserRealmRoleMapper)
+	if err != nil {
+		return err
+	}
+
+	mapFromOpenIdUserRealmRoleMapperToData(openIdUserRealmRoleMapper, data)
+
+	return resourceKeycloakOpenIdUserRealmRoleProtocolMapperRead(data, meta)
+}
+
+func resourceKeycloakOpenIdUserRealmRoleProtocolMapperRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+	realmId := data.Get("realm_id").(string)
+	clientId := data.Get("client_id").(string)
+	clientScopeId := data.Get("client_scope_id").(string)
+
+	openIdUserRealmRoleMapper, err := keycloakClient.GetOpenIdUserRealmRoleProtocolMapper(realmId, clientId, clientScopeId, data.Id())
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	mapFromOpenIdUserRealmRoleMapperToData(openIdUserRealmRoleMapper, data)
+
+	return nil
+}
+
+func resourceKeycloakOpenIdUserRealmRoleProtocolMapperUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	openIdUserRealmRoleMapper := mapFromDataToOpenIdUserRealmRoleProtocolMapper(data)
+
+	err := keycloakClient.ValidateOpenIdUserRealmRoleProtocolMapper(openIdUserRealmRoleMapper)
+	if err != nil {
+		return err
+	}
+
+	err = keycloakClient.UpdateOpenIdUserRealmRoleProtocolMapper(openIdUserRealmRoleMapper)
+	if err != nil {
+		return err
+	}
+
+	return resourceKeycloakOpenIdUserRealmRoleProtocolMapperRead(data, meta)
+}
+
+func resourceKeycloakOpenIdUserRealmRoleProtocolMapperDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	clientId := data.Get("client_id").(string)
+	clientScopeId := data.Get("client_scope_id").(string)
+
+	return keycloakClient.DeleteOpenIdUserRealmRoleProtocolMapper(realmId, clientId, clientScopeId, data.Id())
+}


Test patch:
diff --git a/provider/generic_protocol_mapper_validation_test.go b/provider/generic_protocol_mapper_validation_test.go
index d6a359e..a3e54e9 100644
--- a/provider/generic_protocol_mapper_validation_test.go
+++ b/provider/generic_protocol_mapper_validation_test.go
@@ -2,10 +2,11 @@ package provider
 
 import (
 	"fmt"
-	"github.com/hashicorp/terraform/helper/acctest"
-	"github.com/hashicorp/terraform/helper/resource"
 	"regexp"
 	"testing"
+
+	"github.com/hashicorp/terraform/helper/acctest"
+	"github.com/hashicorp/terraform/helper/resource"
 )
 
 /*
@@ -256,6 +257,30 @@ func TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_clientScopeDuplicateNameV
 	})
 }
 
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_clientScopeDuplicateNameValidation(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	clientId := "terraform-client-" + acctest.RandString(10)
+	mapperName := "terraform-user-realm-role-mapper-" + acctest.RandString(5)
+
+	fullNameProtocolMapperResourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper_client_scope"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testGenericProtocolMapperValidation_clientScopeUserRealmRoleMapper(realmName, clientId, mapperName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(fullNameProtocolMapperResourceName),
+			},
+			{
+				Config:      testGenericProtocolMapperValidation_clientScopeUserRealmRoleAndHardcodedClaimMapper(realmName, clientId, mapperName),
+				ExpectError: regexp.MustCompile("validation error: a protocol mapper with name .+ already exists for this client"),
+			},
+		},
+	})
+}
+
 /*
  * Protocol mappers must be attached to either a client or client scope.  The following tests assert that errors are raised
  * if neither are specified.
@@ -341,6 +366,22 @@ func TestAccKeycloakOpenIdHardcodedClaimProtocolMapper_validateClientOrClientSco
 	})
 }
 
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_validateClientOrClientScopeSet(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers: testAccProviders,
+		PreCheck:  func() { testAccPreCheck(t) },
+		Steps: []resource.TestStep{
+			{
+				Config:      testKeycloakOpenIdUserRealmRoleProtocolMapper_parentResourceValidation(realmName, mapperName),
+				ExpectError: regexp.MustCompile("validation error: one of ClientId or ClientScopeId must be set"),
+			},
+		},
+	})
+}
+
 func testGenericProtocolMapperValidation_clientGroupMembershipMapper(realmName, clientId, mapperName string) string {
 	return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
@@ -566,6 +607,29 @@ resource "keycloak_openid_group_membership_protocol_mapper" "group_membership_ma
 }`, realmName, clientScopeId, mapperName)
 }
 
+func testGenericProtocolMapperValidation_clientUserRealmRoleMapper(realmName, clientId, mapperName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "openid_client" {
+	realm_id    = "${keycloak_realm.realm.id}"
+	client_id   = "%s"
+
+	access_type = "BEARER-ONLY"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_id        = "${keycloak_openid_client.openid_client.id}"
+
+	claim_name       = "foo"
+	claim_value_type = "String"
+}`, realmName, clientId, mapperName)
+}
+
 func testGenericProtocolMapperValidation_clientScopeFullNameMapper(realmName, clientId, mapperName string) string {
 	return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
@@ -624,6 +688,25 @@ resource "keycloak_openid_user_property_protocol_mapper" "user_property_mapper_c
 }`, realmName, clientId, mapperName)
 }
 
+func testGenericProtocolMapperValidation_clientScopeUserRealmRoleMapper(realmName, clientId, mapperName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client_scope" "client_scope" {
+	name     = "%s"
+	realm_id = "${keycloak_realm.realm.id}"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client_scope" {
+	name            = "%s"
+	realm_id        = "${keycloak_realm.realm.id}"
+	client_scope_id = "${keycloak_openid_client_scope.client_scope.id}"
+	claim_name      = "bar-property"
+}`, realmName, clientId, mapperName)
+
+}
 func testGenericProtocolMapperValidation_clientScopeFullNameAndGroupMembershipMapper(realmName, clientScopeId, mapperName string) string {
 	return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
@@ -734,6 +817,35 @@ resource "keycloak_openid_hardcoded_claim_protocol_mapper" "hardcoded_claim_mapp
 }`, realmName, clientId, mapperName, mapperName)
 }
 
+func testGenericProtocolMapperValidation_clientScopeUserRealmRoleAndHardcodedClaimMapper(realmName, clientId, mapperName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client_scope" "client_scope" {
+	name     = "%s"
+	realm_id = "${keycloak_realm.realm.id}"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client_scope" {
+	name            = "%s"
+	realm_id        = "${keycloak_realm.realm.id}"
+	client_scope_id = "${keycloak_openid_client_scope.client_scope.id}"
+	claim_name      = "bar-property"
+}
+
+resource "keycloak_openid_hardcoded_claim_protocol_mapper" "hardcoded_claim_mapper_client_scope" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_scope_id  = "${keycloak_openid_client_scope.client_scope.id}"
+
+	claim_name       = "foo"
+	claim_value      = "bar"
+	claim_value_type = "String"
+}`, realmName, clientId, mapperName, mapperName)
+}
+
 func testKeycloakOpenIdFullNameProtocolMapper_parentResourceValidation(realmName, mapperName string) string {
 	return fmt.Sprintf(`
 resource "keycloak_realm" "realm" {
@@ -802,3 +914,18 @@ resource "keycloak_openid_hardcoded_claim_protocol_mapper" "hardcoded_claim_mapp
 	claim_value_type = "String"
 }`, realmName, mapperName)
 }
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapper_parentResourceValidation(realmName, mapperName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client_scope" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+
+	claim_name       = "foo"
+	claim_value_type = "String"
+}`, realmName, mapperName)
+}
diff --git a/provider/resource_keycloak_openid_user_realm_role_protocol_mapper_test.go b/provider/resource_keycloak_openid_user_realm_role_protocol_mapper_test.go
new file mode 100644
index 0000000..dc5f919
--- /dev/null
+++ b/provider/resource_keycloak_openid_user_realm_role_protocol_mapper_test.go
@@ -0,0 +1,432 @@
+package provider
+
+import (
+	"fmt"
+	"regexp"
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/acctest"
+	"github.com/hashicorp/terraform/helper/resource"
+	"github.com/hashicorp/terraform/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_basicClient(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	clientId := "terraform-client-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+
+	resourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper_client"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_client(realmName, clientId, mapperName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_basicClientScope(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	clientScopeId := "terraform-client-scope-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+
+	resourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper_client_scope"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_clientScope(realmName, clientScopeId, mapperName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_import(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	clientId := "terraform-openid-client-" + acctest.RandString(10)
+	clientScopeId := "terraform-client-scope-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+
+	clientResourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper_client"
+	clientScopeResourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper_client_scope"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdFullNameProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_import(realmName, clientId, clientScopeId, mapperName),
+				Check: resource.ComposeTestCheckFunc(
+					testKeycloakOpenIdUserRealmRoleProtocolMapperExists(clientResourceName),
+					testKeycloakOpenIdUserRealmRoleProtocolMapperExists(clientScopeResourceName),
+				),
+			},
+			{
+				ResourceName:      clientResourceName,
+				ImportState:       true,
+				ImportStateVerify: true,
+				ImportStateIdFunc: getGenericProtocolMapperIdForClient(clientResourceName),
+			},
+			{
+				ResourceName:      clientScopeResourceName,
+				ImportState:       true,
+				ImportStateVerify: true,
+				ImportStateIdFunc: getGenericProtocolMapperIdForClientScope(clientScopeResourceName),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_update(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	clientId := "terraform-client-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+
+	claimName := "claim-name-" + acctest.RandString(10)
+	updatedClaimName := "claim-name-update-" + acctest.RandString(10)
+
+	resourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_claim(realmName, clientId, mapperName, claimName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_claim(realmName, clientId, mapperName, updatedClaimName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_createAfterManualDestroy(t *testing.T) {
+	var mapper = &keycloak.OpenIdUserRealmRoleProtocolMapper{}
+
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	clientId := "terraform-client-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+
+	resourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper_client"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_client(realmName, clientId, mapperName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperFetch(resourceName, mapper),
+			},
+			{
+				PreConfig: func() {
+					keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+					err := keycloakClient.DeleteOpenIdUserRealmRoleProtocolMapper(mapper.RealmId, mapper.ClientId, mapper.ClientScopeId, mapper.Id)
+					if err != nil {
+						t.Error(err)
+					}
+				},
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_client(realmName, clientId, mapperName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_validateClaimValueType(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(10)
+	invalidClaimValueType := acctest.RandString(5)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config:      testKeycloakOpenIdUserRealmRoleProtocolMapper_validateClaimValueType(realmName, mapperName, invalidClaimValueType),
+				ExpectError: regexp.MustCompile("expected claim_value_type to be one of .+ got " + invalidClaimValueType),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateClientIdForceNew(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	clientId := "terraform-client-" + acctest.RandString(10)
+	updatedClientId := "terraform-client-update-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+
+	claimName := "claim-name-" + acctest.RandString(10)
+	resourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_claim(realmName, clientId, mapperName, claimName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_claim(realmName, updatedClientId, mapperName, claimName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateClientScopeForceNew(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+	clientScopeId := "terraform-client-" + acctest.RandString(10)
+	newClientScopeId := "terraform-client-scope-" + acctest.RandString(10)
+	resourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper_client_scope"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_clientScope(realmName, clientScopeId, mapperName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_clientScope(realmName, newClientScopeId, mapperName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakOpenIdUserRealmRoleProtocolMapper_updateRealmIdForceNew(t *testing.T) {
+	realmName := "terraform-realm-" + acctest.RandString(10)
+	newRealmName := "terraform-realm-" + acctest.RandString(10)
+	clientId := "terraform-client-" + acctest.RandString(10)
+	mapperName := "terraform-openid-connect-user-realm-role-mapper-" + acctest.RandString(5)
+
+	claimName := "claim-name-" + acctest.RandString(10)
+	resourceName := "keycloak_openid_user_realm_role_protocol_mapper.user_realm_role_mapper"
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_claim(realmName, clientId, mapperName, claimName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+			{
+				Config: testKeycloakOpenIdUserRealmRoleProtocolMapper_claim(newRealmName, clientId, mapperName, claimName),
+				Check:  testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName),
+			},
+		},
+	})
+}
+
+func testAccKeycloakOpenIdUserRealmRoleProtocolMapperDestroy() resource.TestCheckFunc {
+	return func(state *terraform.State) error {
+		for resourceName, rs := range state.RootModule().Resources {
+			if rs.Type != "keycloak_openid_user_realm_role_protocol_mapper" {
+				continue
+			}
+
+			mapper, _ := getUserRealmRoleMapperUsingState(state, resourceName)
+
+			if mapper != nil {
+				return fmt.Errorf("openid user attribute protocol mapper with id %s still exists", rs.Primary.ID)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapperExists(resourceName string) resource.TestCheckFunc {
+	return func(state *terraform.State) error {
+		_, err := getUserRealmRoleMapperUsingState(state, resourceName)
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapperFetch(resourceName string, mapper *keycloak.OpenIdUserRealmRoleProtocolMapper) resource.TestCheckFunc {
+	return func(state *terraform.State) error {
+		fetchedMapper, err := getUserRealmRoleMapperUsingState(state, resourceName)
+		if err != nil {
+			return err
+		}
+
+		mapper.Id = fetchedMapper.Id
+		mapper.ClientId = fetchedMapper.ClientId
+		mapper.ClientScopeId = fetchedMapper.ClientScopeId
+		mapper.RealmId = fetchedMapper.RealmId
+
+		return nil
+	}
+}
+
+func getUserRealmRoleMapperUsingState(state *terraform.State, resourceName string) (*keycloak.OpenIdUserRealmRoleProtocolMapper, error) {
+	rs, ok := state.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found in TF state: %s ", resourceName)
+	}
+
+	id := rs.Primary.ID
+	realm := rs.Primary.Attributes["realm_id"]
+	clientId := rs.Primary.Attributes["client_id"]
+	clientScopeId := rs.Primary.Attributes["client_scope_id"]
+
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	return keycloakClient.GetOpenIdUserRealmRoleProtocolMapper(realm, clientId, clientScopeId, id)
+}
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_client(realmName, clientId, mapperName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "openid_client" {
+	realm_id  = "${keycloak_realm.realm.id}"
+	client_id = "%s"
+
+	access_type = "BEARER-ONLY"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_id        = "${keycloak_openid_client.openid_client.id}"
+
+	claim_name       = "foo"
+	claim_value_type = "String"
+}`, realmName, clientId, mapperName)
+}
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapper_basic_clientScope(realmName, clientScopeId, mapperName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client_scope" "client_scope" {
+	name     = "%s"
+	realm_id = "${keycloak_realm.realm.id}"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client_scope" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_scope_id  = "${keycloak_openid_client_scope.client_scope.id}"
+
+	claim_name       = "foo"
+	claim_value_type = "String"
+}`, realmName, clientScopeId, mapperName)
+}
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapper_claim(realmName, clientId, mapperName, claimName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "openid_client" {
+	realm_id  = "${keycloak_realm.realm.id}"
+	client_id = "%s"
+
+	access_type = "BEARER-ONLY"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_id        = "${keycloak_openid_client.openid_client.id}"
+
+	claim_name       = "%s"
+	claim_value_type = "String"
+}`, realmName, clientId, mapperName, claimName)
+}
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapper_import(realmName, clientId, clientScopeId, mapperName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "openid_client" {
+	realm_id    = "${keycloak_realm.realm.id}"
+	client_id   = "%s"
+
+	access_type = "BEARER-ONLY"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_id        = "${keycloak_openid_client.openid_client.id}"
+
+	claim_name       = "foo"
+	claim_value_type = "String"
+}
+
+resource "keycloak_openid_client_scope" "client_scope" {
+	name     = "%s"
+	realm_id = "${keycloak_realm.realm.id}"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_client_scope" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_scope_id  = "${keycloak_openid_client_scope.client_scope.id}"
+
+	claim_name       = "foo"
+	claim_value_type = "String"
+}`, realmName, clientId, mapperName, clientScopeId, mapperName)
+}
+
+func testKeycloakOpenIdUserRealmRoleProtocolMapper_validateClaimValueType(realmName, mapperName, claimValueType string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "openid_client" {
+	realm_id  = "${keycloak_realm.realm.id}"
+	client_id = "openid-client"
+
+	access_type = "BEARER-ONLY"
+}
+
+resource "keycloak_openid_user_realm_role_protocol_mapper" "user_realm_role_mapper_validation" {
+	name             = "%s"
+	realm_id         = "${keycloak_realm.realm.id}"
+	client_id        = "${keycloak_openid_client.openid_client.id}"
+
+	claim_name      = "foo"
+	claim_value_type = "%s"
+}`, realmName, mapperName, claimValueType)
+}