Terraform Cloud/Enterprise Easy Onboarding
Written: 2021-10-18
Author: WhatsARanjit
Links:
The problem
You are using Terraform Cloud/Enterprise (will refer to both as TFC). Managing a few to several workspaces is easy within the UI. But what happens if I need to onboard hundreds of teams? How do I manage permissions, policy, and/or versioning? How do I do this as code?
The fix
The TFC API allows us to do a lot of things. Furthermore, the TFC provider allows us to use this API as Terraform code, just like any other resources.
Setup
We’ll assume some things are already set up, although many of these can be done with a different layer of Terraform code:
-
TFC organization is created
-
TFC organization connection to your preferred VCS is created
-
Intended RBAC users are already registered TFC users
Usage
Required Variables
TFC Token
The TFC token to use with enough permissions to manage workspaces. For more information on generating tokens, please read:https://www.terraform.io/docs/enterprise/users-teams-organizations/users.html#api-tokens
-
Source the WhatsARanjit Onboarding Module
-
Enter required variables via CLI or TFC
-
organization
TFC organization under which to create the workspace -
workspace_name
Unique name of the workspace to track -
workspace_owner_email
Email address of the TFC user who has admin access -
workspace_vcs_identifier
VCS repo in the format<vsc_org>/<repo_name>
-
workspace_oauth_id
OAuth ID seen in the TFC UI
-
Optional Variables
Some extra options if you need:
-
workspace_description
Description of workspace for your records. -
workspace_terraform_version
Version of Terraform to use. Defaults to latest. -
workspace_tags
List of tags to apply to workspace. -
workspace_vcs_branch
VCS branch to use other than VCS default. -
workspace_vcs_directory
VCS working directory other than root to use. -
variables
Map of variables to use. Check examples for map format. -
workspace_read_access_emails
Optional list of reader emails. -
workspace_read_access_emails
Optional list of writer emails. -
workspace_read_access_emails
Optional access of planner emails.
…After some variables we can start to play around. As a best practice, you do not want to include secret/sensitive data as part of your code. You can supply them through Vault or other lookups and template them into your Terraform code. Check out these other resources for more imformation.
Module implementation
module "teamA" {
source = "github.com/WhatsARanjit/terraform-onboarding-module"
# Workspace setup
organization = "my_orgaization_name"
workspace_name = "onboarding_test"
workspace_owner_email = "owner@org.com"
workspace_description = "Onboarding Team A"
workspace_vcs_identifier = "WhatsARanjit/terraform-random-app"
workspace_oauth_id = "oc-orgid123456"
workspace_tags = [
"teamA",
"onboarding",
]
# Variables
variables = {
bu = {
value = "onboarding"
}
TF_LOG = {
value = "DEBUG"
category = "env"
}
admin_password = {
value = "P@ssw0rd"
description = "Secure access to nothing"
sensitive = true
}
default_tags = {
value = "{ \"environment\" = \"test\", \"owner\" = \"WhatsARanjit\" }"
hcl = true
}
AWS_ACCESS_KEY_ID = {
value = "FOO"
category = "env"
sensitive = true
}
AWS_SECRET_KEY_ID = {
value = "BAR",
category = "env"
sensitive = true
}
}
# RBAC
# Optional built-in RBAC teams
## Read
workspace_read_access_emails = [
"ranjit+ops@myorg.com"
]
## Write
workspace_write_access_emails = [
"ranjit+dev@myorg.com"
]
## Plan
workspace_plan_access_emails = [
"ranjit+test@myorg.com"
]
}
In the end
We want to onboard a new project/BU/internal customer onto TFC/E without too much effort. The great news is we can Terraform for TFC/E! So when there’s a new thing, we can use internal Terraform code to create a new workspace, VCS configuration, permissions, run triggers, notifications, etc, all through Terraform code. The example creates the following for you:
- Workspace with a VCS repo
- Terraform and environment variables
- Workspace tags for easy searching/views
- Generic read, write, and plan teams in RBAC
Caveats
What this repo can’t do just yet-
- The VCS connection ID must be provided; it can’t be looked up by name. This is kind of a pain.
- Sensitive variables must be provided in code, although there is probably a way to template out the variable input and use the
vault
provider to pass in secret information. - Non-global Sentinel policy is applied to workspaces on the policyset level. When the workspace is created, a plan/apply will be invoked automatically. This will be before any new policy applications. This means a new workspace potentially can do non-compliant things until the relevant policyset(s) are updated to include the new workspace.