TrademarkTrademark
Features
Documentation

How To Manage Scalr RBAC At Scale Using The Scalr Provider

Learn how Scalr allows for IAM to be control and managed to suit your specific needs.
Ryan FeeJuly 19, 2022
How To Manage Scalr RBAC At Scale Using The Scalr Provider
Key takeaways
  • Scalr RBAC is managed in code with the Scalr Terraform provider, defining roles, teams, and access policies to scale identity and access management.
  • Three objects drive Scalr RBAC: roles (permissions), users or teams, and access policies that link a team to a role at a defined scope.
  • Every team must hold at least the account-min-access role at the account scope, then receive additional roles scoped to the environments where they create runs.
  • Automating RBAC supports vending pre-configured Scalr environments so onboarded teams can focus solely on their Terraform deployments.

As mentioned in the last blog on granular RBAC, the way Scalr does IAM is a key differentiator from the competition. Scalr allows for custom roles and access policies at every scope in the product, which makes the RBAC model very flexible. That flexibility helps, but only if you manage RBAC in a way that scales. The way to do that is to automate it with the Scalr provider.

Automating RBAC is one step in a larger effort to "vend" Scalr environments, which is a best practice when onboarding new applications and teams. Typically you build a Scalr module that creates teams and associates a role with each team. The module then creates an environment and links provider credentials, policies, teams, variables, and modules to it. A team can then log into a pre-configured environment and focus on their Terraform deployments. (If you already have a vending machine for your cloud accounts and subscriptions, you can extend it to Scalr as well.) The rest of this post walks through the technical detail of automating Scalr RBAC.

There are a few objects that need to be managed:

  • Roles - The permissions a team or user has.
  • Users/Teams - The users or teams who have access to Scalr.
  • Access Policies - The object that links a team to a role and defines the scope at which the linking happens.

In this tutorial, we'll use the Scalr provider to assign a team with a custom role to an environment. We'll walk through each piece of code first so you can see how it's used. Near the bottom of the post you'll find the end result: a single main.tf with all of the code in it.

First, let's set up the provider in a providers.tf. Get the provider information from https://registry.scalr.io/:

terraform {
  required_providers {
      scalr = {
          source = "registry.scalr.io/scalr/scalr"
          version= "1.0.0-rc32"
      }
  }
}

Let's start constructing our main.tf. First we'll add a local to define the account:

##Define your account and environment ID##
locals {
  account_id  = "<your-account-id>"
}

Next add some data sources to pull IDs:

data "scalr_environment" "example" {
  name = "Research-Development"
  account_id = local.account_id
}
 
data "scalr_role" "example" {
  name = "account-min-access"
}

Now, let's create a predefined set of roles that all teams will be assigned. The majority of the time, roles are created upfront and then modified as needed, this is not something that is updated frequently. For these purposes, we'll create a role, which is used for the applications teams who need to create Terraform runs only.

resource "scalr_role" "planner" {
  name         = "Plan Creation"
  account_id = local.account_id
  description = "Ability to create Terraform runs, but not approve"
 
  permissions = [
    "accounts:read",
    "environments:read",
    "runs:cancel",
    "runs:create",
    "workspaces:read",
    "workspaces:set-schedule",
    "workspaces:update"
  ]
}

Next, let's add a team. Normally, you would likely want to use Terraform variables to reuse the code, but for these purposes we'll hardcode and use locals for the account/environment ID. Further down in the blog you will see all of the code with the locals defined:

resource "scalr_iam_team" "example" {
  name        = "myfirstscalrteam"
  description = "Scalr Example Team"
  account_id  = local.account_id
}

Lastly, we need to create an access policy to attach the role to a team and link the team to a scope in Scalr. All teams must have at least the 'account-min-access' role at the account scope to have access to Scalr, and then they can be added to the environment in which they will create runs:

##Link to the account first with minimal access##
resource "scalr_access_policy" "team_min_access_to_acc_scope" {
  subject {
    type = "team"
    id = scalr_iam_team.example.id
  }
  scope {
    type = "account"
    id = local.account_id
  }
 
  role_ids = [
    data.scalr_role.example.id
  ]
}
 
##Link to an environment with role created earlier##
resource "scalr_access_policy" "team_access_to_env_scope" {
   subject {
     type = "team"
     id = scalr_iam_team.example.id
   }
   scope {
     type = "environment"
     id = data.scalr_environment.example.id
   }
 
   role_ids = [
     scalr_role.planner.id
   ]
}

All together, this looks like:

##Define your account ID##
locals {
  account_id  = "acc-sscctbisjkl35b8"
}
 
data "scalr_environment" "example" {
  name = "Research-Development"
  account_id = local.account_id
}
 
data "scalr_role" "example" {
  name = "account-min-access"
}
 
resource "scalr_role" "planner" {
  name         = "Plan Creation"
  account_id = local.account_id
  description = "Ability to create Terraform runs, but not approve"
 
  permissions = [
    "accounts:read",
    "environments:read",
    "runs:cancel",
    "runs:create",
    "workspaces:read",
    "workspaces:set-schedule",
    "workspaces:update"
  ]
}
 
resource "scalr_iam_team" "example" {
  name        = "myfirstscalrteam"
  description = "Scalr Example Team"
  ##Add your own account ID##
  account_id  = local.account_id
}
 
##Link to the account first with minimal access##
resource "scalr_access_policy" "team_min_access_to_acc_scope" {
  subject {
    type = "team"
    id = scalr_iam_team.example.id
  }
  scope {
    type = "account"
    id = local.account_id
  }
 
  role_ids = [
    data.scalr_role.example.id
  ]
}
 
##Link to an environment with role created earlier##
resource "scalr_access_policy" "team_access_to_env_scope" {
  subject {
    type = "team"
    id = scalr_iam_team.example.id
  }
  scope {
    type = "environment"
    id = data.scalr_environment.example.id
  }
 
  role_ids = [
    scalr_role.planner.id
  ]
}

To execute this, you have a couple of options:

I'm choosing to use a VCS backed workspace:

Scalr VCS backed workspace configured for the RBAC tutorial

Upon execution we see that the four resources have been created:

Scalr run output showing four RBAC resources successfully created

And can verify this by looking at each object in the account scope:

Team creation:

Newly created Scalr team shown in the account scope

Role creation:

Newly created Plan Creation role shown in the account scope

Account scope access policy:

Account scope access policy linking the team to the min-access role

Environment scope access policy:

Environment scope access policy linking the team to the Plan Creation role

What's next

Now that you have learned the basics of how to use the Scalr provider to manage IAM, you can take it to the next level with these few suggestions:

  • Separate out the role resource into its own module. You most likely won't create a new role every time a team onboards, instead reuse common roles. We kept it in the same main.tf code for example purposes in this blog.
  • Use this code as a starting point for a module and use variable files to make the code reusable.
  • Incorporate this into a vending machine. As teams onboard into Scalr they usually get their own environment. Add more code which will create the environments, link objects (teams, policies, variables, and more) to fully automate your onboarding process.

Look for more examples on other concepts coming soon.

About the author
Ryan Feedirector of platform engineering at Scalr
Ryan Fee is the director of platform engineering at Scalr, with over 15 years of experience improving infrastructure experiences at companies large and small.