Back to changelog
Improvement
•2 minute read

Redshift: Manage IAM Users

Atlas now manages the Redshift users of IAM users and IAM roles like any other user. Roles and users can be managed in an environment of their own, without a dev database.

Redshift creates a database user for each IAM user and IAM role that signs in, named iam:<name> and iamr:<name>. Atlas used to only read these users. It now manages them like any other user: create them, add them to roles and groups, grant them permissions, and drop them.

Defining IAM users

Declare an IAM user or IAM role with a user block named after its Redshift user, including the prefix:

// The IAM user "alice".user "iam:alice" {}
// The IAM role "etl".user "iamr:etl" {}

The name must match the IAM user or role exactly, or Atlas creates a separate user that the identity never signs in as. Because the name contains a colon, other blocks reference it with brackets, user["iam:alice"], where a regular user uses a dot, user.app_writer. The setup below shows both.

Recommended setup

Roles and users belong to the whole Redshift cluster, not to a single database. To plan schema changes, Atlas first applies the desired schema to a dev database, and a role created there collides with the real one when both are on the same cluster. Keep roles and users in an environment of their own:

  • roles creates and updates roles and users. It needs no dev database.
  • app manages schemas, tables, and the permissions on them. It uses a dev database and only refers to roles and users.

Roles and users

Atlas plans roles and users by comparing them with the cluster directly, so this environment runs without a dev database:

atlas.hcl
env "roles" {  url = getenv("REDSHIFT_URL")
  schema {    src = "file://roles.hcl"    mode {      roles = true    }  }}
roles.hcl
role "app_reader" {}
user "app_writer" {}
user "iam:alice" {  member_of = [role.app_reader]}
user "iamr:etl" {}
atlas schema apply --env roles
CREATE ROLE "app_reader";CREATE USER "app_writer" PASSWORD DISABLE;CREATE USER "iam:alice" PASSWORD DISABLE;GRANT ROLE "app_reader" TO "iam:alice";CREATE USER "iamr:etl" PASSWORD DISABLE;

Schemas and permissions

Permissions stay next to the tables they apply to. Role management is off in this environment, so it never creates or drops a role or user. Mark each role and user that schema.hcl grants to as external = true, so Atlas refers to it without managing it:

atlas.hcl
env "app" {  url = getenv("REDSHIFT_URL")  dev = getenv("REDSHIFT_DEV_URL")
  schema {    src = "file://schema.hcl"    mode {      permissions = true    }  }}
schema.hcl
user "app_writer" {  external = true}
user "iam:alice" {  external = true}
permission {  to         = user.app_writer  for        = table.orders  privileges = [INSERT]}
permission {  to         = user["iam:alice"]  for        = table.orders  privileges = [SELECT]}
table "orders" {  ...}

Apply the roles environment first, so the roles and users exist before the permissions grant to them:

$ atlas schema apply --env roles$ atlas schema apply --env app
Note: Avoid creating iam: and iamr: users in migration files. A file that creates one fails if the user already exists, for example after the IAM user or role has signed in once.

Getting Started

The Redshift driver is part of Atlas Pro:

$ atlas login

See the HCL reference for the user block, and the Redshift security guide for roles, groups, and permissions.

improvementredshiftuserspermissionsiamdev databaseatlas pro