Apply for invite to IaCP

Variables

Overview

There are two types of variables that are used in Scalr IaC Platform:

  • Terraform variables: Variables used in a Terraform template to gather values to inject into the Terraform template.

  • Global variables: Multi-purpose key value store objects that can be used for input and tied to Terraform templates for policy enforcement.

These Terraform variables can be bound to Scalr global variables and Scalr policies in order to provide administrators with powerful controls over the values that can be entered by users when requesting services from the template registry.

Terraform Variables

Terraform variables are used to gather information to inject into a Terraform template. This allows for easy Terraform template re-use when sharing templates across an organization. Click here to find out more about variables. NEWWIN

In a Workspace

If a workspace is created through the UI manually, the variable names and values will need to be entered directly in the workspace prior to kicking off a Terraform run. In a future release, the information will be automatically populated based on the ingestion of the variables.tf file from the VCS provider. To create or update the Terraform variables in the workspace, click on workspaces and then variables:

../_images/workspace_variable.png

In the Template Registry

Terraform input variables can be use in Scalr IaC Platform to set default values or to prompt endusers for values in the UI, if using the template registry. Scalr IaC Platform will use all input variables found in the all Terraform files in the repository to create input prompts. These variable will be presented as either “required” or “optional” depending on how they are configured. Required variables have no default and optional variables have a default.

An example of a required variable would be a key without a value as seen here:

variable "region" {}

In this scenario, the user will be prompted to fill in the information before deploying in the template registry or workspace:

../_images/required_var.png

Using the same example, you can make this an “optional” variable, by having a pre-defined value:

variable "region" {
  default = "us-east-1"
}
../_images/optional_var.png

Terraform variables are helpful, but don’t necessarily put constraints on the values that can be entered. The following sections teach you how to bind Terraform variables to apply controls on the values that can be entered.

Global Variables

Global variables are multi-purpose key value store objects that can be used for input from users or admins. Global variables can be used for the following:

  • To inject values from the template registry into Terraform variables.

  • To inject values from the template registry into Scalr policy (naming conventions, tagging, etc)

  • Limit end users choices for Terraform variables.

Creating Global Variables

Global variables can be created, updated, edited, or deleted at the Scalr, account, environment or workspace scope. To create a global variable at the Scalr, account, or environment scope you can click on the “GV” button.

You have a few options when creating a global variable:

../_images/new_gv.png

Item

Type

Description

Name

Metadata

Name of the global variable

Category

Metadata

Category that the global variable falls into

Description

Metadata

Description of the global variable

HID Hidden

Flag

The value cannot be seen at a lower scope

LOCK Locked

Flag

The value cannot be changed at a lower scope. However if a required scope is set the value can be changed at that scope.

Required

Flag

The value must be set at a specific scope

Custom

Type

A regular expression can be created for pattern validation

JSON

Type

The values must be in a JSON format

List

Type

The label is what is presented in the dropdown and the value is what is used on the backend. If a label is not used, the value will be presented in the dropdown.

Remote list

Type

The values will be pulled from a remote list. The response must be JSON.

Once the global variable is created, click save and you will be able to use it in the various use cases below.

Global Variable Formatting

If a Scalr global variable is mapped to a Terraform input variable and the Scalr global variable has printf and/or REGEX formatting options, these will be applied to template registry inputs.

Formatting is validated on exit from the field and warning will be displayed.

Variable:

../_images/format_var.png

Warning:

../_images/format_warn.png

Binding Variables

The binding of Terraform variables to Scalr global variables and policies is achieved by creating a new file scalr-module.hcl in your Terraform template. The details for achieving global variable and policy binding are described in sections below.

scalr-module.hcl has the following capabilities:

  • Written in HCL language to avoid learning a new language.

  • Built-in versioning.

  • Bind Terraform variables to global variables.

  • Bind Terraform variables to Scalr IaC Platform policies.

  • Terraform itself will ignore the file, it is specific to Scalr IaC Platform.

scalr-module.hcl supports and requires versioning:

version: "v1"

Binding to Global Variables

Terraform input variables can be bound to Scalr global variables in order to set a list of allowed values and/or define formatting rules. A list of values will be presented to the user as a drop down list in the UI. As an example, you might require your users to input a billing code prior to provisioning their resources. To do this with variables, you would do the following:

Define a Terraform variable like this:

variable "billing_code" {}

Create a scalr-module.hcl file with the following (versioning is required):

version = "v1"

variable "billing_code" {
  global_variable = "billing_code"
}

In the UI, create global variable called “billing_code” of type “list” with a set of values. Scalr will display the label for each value in the resulting drop down:

../_images/gv.png

Note

The Terraform input variable and the Scalr global variable DO NOT have to have the same name.

Now in the template registry you will have a “billing_code” field that is mapped to the Terraform variable:

../_images/bind_gv.png

Formatting via print directives and/or REGEX is enforced in the UI with warnings displayed if any violations occur.

Note that the name of the variable displayed in the UI is the Terraform variable name and not the Scalr global variable name. The {x} indicates the field is bound to a Scalr global variable.

Binding to Policy

To make Terraform variables even more powerful, you can combine them with policy to ensure users are deploying their resources in a compliant way. Going back to to the region example above, you’ll first want to create the policy at the account scope. To do this, click on the main menu at the account scope MENU_ACC, click on policy, and create a cloud.location policy for the cloud you are building in:

../_images/variables_policy.png

In the example above we are restricting the user to deploy in us-east-1 or us-west1 in AWS.

Now in the variables.tf, add the following if it is not already there:

variable "region" {}

In the scalr-module.hcl, add the following:

variable "region" {
    policy = "cloud.locations"
    conditions = {
    cloud = "ec2"
  }
}

By connecting policy, variables.tf, and scalr-module.hcl we will now have the user prompted for the region variable and they will be limited to only choose what is part of the policy:

../_images/variables_policy_servicecatalog.png

Input Formatting

If a Terraform variable is pre-populated with a value and a type, this will affect the way they variables are presented in the template registry. In this example, the simple string type variable was used to create a pre-populated field:

../_images/optional_var.png

Also, Scalr will inherit MAP and LIST type Terraform variables to create prompts. This is an example of a MAP variable and it’s prompt:

variable "images" {
  type = "map"
  default = {
    us-east-1 = "image-1234"
    us-west-2 = "image-4567"
  }
}
../_images/map_var.png

This is an example of a LIST variable and it’s prompt:

variable "zones" {
   type = "list"
   default = ["us-east-1a", "us-east-1b"]
}
../_images/list_var.png

Advanced Policy Binding

Policy Conditions

Policy binding must include any and all required conditions specified in the Scalr policy itself. Policy conditions vary between policy types so please check the details of each policy type carefully. Many policies have multiple conditions which can be optional is some cases and mandatory in others.

For example cloud.locations policy can be common to all cloud credentials or specific.

../_images/pol_con_1.png

However in the case of cloud.networks policy credentials and location must be specified by tags is optional_var

../_images/pol_con_2.png

When binding a Terraform input variable to a policy you must include all mandatory conditions and any optional conditions that have been specified in the policy. e.g for cloud.networks a binding entry in scalr-module.hcl to match the above policy would need to be configured as follows.

Note

Credentials are not included in policy bindings as the credentials in Scalr may not be utilized by the Terraform template but the policy still needs to be applied. Credentials can be defined directly in the template or possibly provided by the users during the template registry request.

variable "networks" {
  policy = "cloud.networks"
  conditions = {
    cloud = "ec2"
    cloud.location = "us-west-2"
  }
}

For full details for policy compatibility with Terraform please see Input Policy.

Condition Variables in Policy Bindings

Terraform input variables can be used in the “conditions” clause of policy bindings to allow the applicable policy to be set correctly according to context. For example if a user is given the choices regarding the configuration of the deployment this may affect which policies need to be applied in cases where the policy requires specific conditions. Examples could be things like the location (region) or network.

Taking Location (Region) as an example lets assume we have policies in place for each region that restrict the networks that can be used.

../_images/net_pol.png

We then have an input variable “region”, configured to capture the users required location and variable to capture the required network.

Variable declaration:

variable "region" {}
variable "network" {}

The “network” variable is then bound to policy using the value of the “region” variable.

variable "networks" {
  policy = "cloud.networks"
  conditions = {
    cloud = "ec2"
    cloud.location = "${var.region}"
  }
}

Now the appropriate policy will be used and this will also ensure the use only has the valid values to select from when choosing a network.