Clock
5
min read

Terraform Credential Helper With Scalr

Ryan Fee

Ryan Fee

Director - Solution Architecture

The Terraform credential helper is a great way to authenticate to external Terraform services when using Scalr. By default, Scalr will use the credentials within the context of the account Terraform is running in, but sometimes you may need to call out to something like an external module registry. 

The main use case we normally hear is that a customer is migrating into Scalr, but as part of the migration process, they will need to use an external module registry while migrating to the Scalr private module registry.

In the example in this blog, I am using two separate Scalr accounts to demonstrate the same concept. The two accounts have separate users, module registries, tokens etc. I will be migrating from my “docs.scalr.io” account into the “scalr-demo.scalr.io” account. I have a very basic Terraform example that is pulling a module from the module registry in docs.scalr.io, while the run is actually executing in scalr-demo.scalr.io

##Added scalr-demo.scalr.io as the remote backend##
terraform {
  backend "remote" {
    hostname = "scalr-demo.scalr.io"
    organization = "org-ssccu6d5ch61234"

    workspaces {
      name = "CredHelper"
    }
  }
}

##Added a module that is being pulled from docs.scalr.io##
module "module-ec2" {
	source = "docs.scalr.io/env-t568vsij9i12345/module-ec2/aws"
	version = "0.0.4"

	# Set 1 required variable below.

 	instance_type = "t2.nano"
}

The first thing you’ll want to do is to add the following in your .terraformrc file:

credentials_helper "scalr" {}

The name of the credential does not need to be “scalr”, it can be whatever you want, but it will need to match the name used in the next step when creating the terraform-credentials-<some_name> file.

Then, you’ll want to add the credential helper script to your workspace, specifically the plugins directory:

<workspace>/terraform.d/plugins/terraform-credentials-scalr

In this case, we named terraform-credentials-scalr to match the naming of credentials_helper "scalr" {} in the terraformrc file, but again, any name can be appended to it: terraform-credentials-<some_name>

The contents of terraform-credentials-scalr:

#!/bin/bash
command="$1"
host="$2"
env_token="TF_TOKEN_${host//./_}"
if [ "$command" = "get" ]; then
  if  [ -z "${!env_token}" ]; then
    echo "{}"e
  else
    echo "{ \"token\": \"${!env_token}\" }"
  fi
  exit 0
else
  exit 1
fi

This is just an example, any third party helpers can be used in place of this.

Then, export the token for the module registry where the code will be pulled from, in this case, it is the token from docs.scalr.io. If you notice, the format will always be TF_TOKEN_the_url:

export TF_TOKEN_docs_scalr_io=eyJh…

Once you run terraform init, you will see that it can access the remote registry from the external source.

Initializing modules...
Downloading docs.scalr.io/env-t568vsij9123456/module-ec2/aws 0.0.4 for module-ec2...
- module-ec2 in .terraform/modules/module-ec2

Initializing the backend...

Initializing provider plugins...
- Using previously-installed hashicorp/aws v4.4.0

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, we recommend adding version constraints in a required_providers block
in your configuration, with the constraint strings suggested below.

* hashicorp/aws: version = "~> 4.4.0"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

That’s it! It is as simple as that to plug into external services while executing your workflows in Scalr.