@@ -34,6 +34,7 @@ const (
3434 roleRolesAttr = "roles"
3535 roleSearchPathAttr = "search_path"
3636 roleStatementTimeoutAttr = "statement_timeout"
37+ roleAssumeRoleAttr = "assume_role"
3738
3839 // Deprecated options
3940 roleDepEncryptedAttr = "encrypted"
@@ -167,6 +168,11 @@ func resourcePostgreSQLRole() *schema.Resource {
167168 Description : "Abort any statement that takes more than the specified number of milliseconds" ,
168169 ValidateFunc : validation .IntAtLeast (0 ),
169170 },
171+ roleAssumeRoleAttr : {
172+ Type : schema .TypeString ,
173+ Optional : true ,
174+ Description : "Role to switch to at login" ,
175+ },
170176 },
171177 }
172178}
@@ -301,6 +307,10 @@ func resourcePostgreSQLRoleCreate(db *DBConnection, d *schema.ResourceData) erro
301307 return err
302308 }
303309
310+ if err = setAssumeRole (txn , d ); err != nil {
311+ return err
312+ }
313+
304314 if err = txn .Commit (); err != nil {
305315 return fmt .Errorf ("could not commit transaction: %w" , err )
306316 }
@@ -446,6 +456,7 @@ func resourcePostgreSQLRoleReadImpl(db *DBConnection, d *schema.ResourceData) er
446456 d .Set (roleBypassRLSAttr , roleBypassRLS )
447457 d .Set (roleRolesAttr , pgArrayToSet (roleRoles ))
448458 d .Set (roleSearchPathAttr , readSearchPath (roleConfig ))
459+ d .Set (roleAssumeRoleAttr , readAssumeRole (roleConfig ))
449460
450461 statementTimeout , err := readStatementTimeout (roleConfig )
451462 if err != nil {
@@ -522,6 +533,20 @@ func readStatementTimeout(roleConfig pq.ByteaArray) (int, error) {
522533 return 0 , nil
523534}
524535
536+ // readAssumeRole searches for a role entry in the rolconfig array.
537+ // In case no such value is present, it returns empty string.
538+ func readAssumeRole (roleConfig pq.ByteaArray ) string {
539+ var res string
540+ var assumeRoleAttr = "role"
541+ for _ , v := range roleConfig {
542+ config := string (v )
543+ if strings .HasPrefix (config , assumeRoleAttr ) {
544+ res = strings .TrimPrefix (config , assumeRoleAttr + "=" )
545+ }
546+ }
547+ return res
548+ }
549+
525550// readRolePassword reads password either from Postgres if admin user is a superuser
526551// or only from Terraform state.
527552func readRolePassword (db * DBConnection , d * schema.ResourceData , roleCanLogin bool ) (string , error ) {
@@ -660,6 +685,10 @@ func resourcePostgreSQLRoleUpdate(db *DBConnection, d *schema.ResourceData) erro
660685 return err
661686 }
662687
688+ if err = setAssumeRole (txn , d ); err != nil {
689+ return err
690+ }
691+
663692 if err = txn .Commit (); err != nil {
664693 return fmt .Errorf ("could not commit transaction: %w" , err )
665694 }
@@ -1008,3 +1037,28 @@ func setIdleInTransactionSessionTimeout(txn *sql.Tx, d *schema.ResourceData) err
10081037 }
10091038 return nil
10101039}
1040+
1041+ func setAssumeRole (txn * sql.Tx , d * schema.ResourceData ) error {
1042+ if ! d .HasChange (roleAssumeRoleAttr ) {
1043+ return nil
1044+ }
1045+
1046+ roleName := d .Get (roleNameAttr ).(string )
1047+ assumeRole := d .Get (roleAssumeRoleAttr ).(string )
1048+ if assumeRole != "" {
1049+ sql := fmt .Sprintf (
1050+ "ALTER ROLE %s SET ROLE TO %s" , pq .QuoteIdentifier (roleName ), pq .QuoteIdentifier (assumeRole ),
1051+ )
1052+ if _ , err := txn .Exec (sql ); err != nil {
1053+ return fmt .Errorf ("could not set role %s for %s: %w" , assumeRole , roleName , err )
1054+ }
1055+ } else {
1056+ sql := fmt .Sprintf (
1057+ "ALTER ROLE %s RESET ROLE" , pq .QuoteIdentifier (roleName ),
1058+ )
1059+ if _ , err := txn .Exec (sql ); err != nil {
1060+ return fmt .Errorf ("could not reset role for %s: %w" , roleName , err )
1061+ }
1062+ }
1063+ return nil
1064+ }
0 commit comments