Skip to content

Template Development Guide

Templates are written in Terraform or OpenTofu, they can be tested outside the ESH environment using the CLI, or they can be tested entirely within ESH.

Prerequisites

  • As a Template developer it is necessary to know how to write Terraform code. Because ESH takes care of the heavy lifting with providers and their target environments, it's very easy to get up to speed with Template development. A simple template can be just a few lines of code.
  • All variables your Template requires should be defined at the root level of your repository. There is no specific requirement to have variables in a specially named file, they can be anywhere in any .tf file in the root of your repository.
  • You will need a repository in which to store your Template. Each Template needs it's own repository so it can be versioned using Git tagging mechanism. The good news is, ESH can provision repositories in all of the major Git platforms via a Template. Once this is setup it is easy for Template developers to create repositories to hold the Organizations Templates.

Create Your First Template

The actual code you write will depend on your Target environment. We will provide 3 examples, AWS, GCP and Azure:

Step 1 - Lets create some Template code

Regardless of the Target, for simplicity, create a single file called main.tf, in that file paste the appropriate content for your Target:

AWS

resource "aws_s3_bucket" "bucket" {
  bucket        = var.bucket_name
}

variable "bucket_name" {
  type = string
  description = "The name of the bucket that will be created"
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

GCP

resource "google_storage_bucket" "static" {
  name          = var.bucket_name
  location      = "US"
  storage_class = "STANDARD"

  uniform_bucket_level_access = true
}

variable "bucket_name" {
  type = string
    description = "The name of the bucket that will be created"
}

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "4.75.1"
    }
  }
}

Azure

resource "azurerm_storage_account" "test" {
  account_replication_type = "GRS"
  account_tier             = "Standard"
  resource_group_name      = var.resource_group_name
  location                 = var.resource_group_location
  name                     = var.storage_account_name
}

variable "resource_group_name" {
    type = string
    description = "The name of the storage account that will be created"
}

variable "resource_group_location" {
    type = string
    description = "The location of the resource group"
}

variable "bucket_name" {
    type = string
    description = "The name of the storage account that will be created"
}

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.71.0"
    }
  }
}

Important: In the examples above, there is no provider specified. This is not necessary in ESH as ESH creates the providers dynamically according to the Target type. This is necessary as the Target knows the required credentials needed for the target environment and writes them into the provider block.

Step 2 - Push it to a repository

Commit and push your code to a new repository in Github, Gitlab, Bitbucket or Azure Repos. Unless your repository is public, ensure you have an access token that has read rights for the repository. Remember, you need a repository per Template as the essential Template versioning in ESH works from Git tags.

Step 3 - Version it

Tag your repository with a version, semantic versioning is recommended. It is easy to tag the repository using the Git CLI.

git tag 0.0.1
git push --tags

Step 4 - Add Template to ESH

Follow the steps in Template Management - Create a Template to add the Template to ESH.

Step 5 - Deploy your Template

You need to test it so ensure the ESH organization admin or your Tenant admin have given you access the appropriate Target and then deploy it according to Create a Deployment

Regions

When ESH writes the provider block, it writes the region that was chosen for the deployment. For this reason regions are not specified in Templates, all Templates should be region agnostic.

In the case of Azure, the region is controlled not by the provider but instead by resource groups. In an Azure template, do not specify location in the resource group as ESH looks at the template code and generates overrides for all azurerm_resource_group resources you specify and replaces any location attributes with the region chosen for the deployment. If you want your template to be able to deploy to an existing resource group, create a data block as follows:

data "azurerm_resource_group" "example" {
  name = var.resource_group
}

Then create a variable called resource_group in your template and the user will be able to pass the deployment the resource group they wish to use. The caveat is that the ESH deployment map will not be able to display the region those resources are deployed to as it only knows the region the user chose when creating the deployment.

Beyond Simple Example Template

It is best practice in Terraform to separate out resources, variables and outputs into separate files. The examples above were condensed into a single file for ease of copy and paste.

Within the scope of the providers we support, see targets, any Terraform code that works with a single provider will work with ESH, so structure your code however you normally do. The single provider contraint is because ESH will write its own provider configuration on deployment of the Template dependent on the Target chosen. The exeption to this is the Kubernates Target type, Kubernates Targets automatically create a Kubernetes and a Helm provider block with appropriate credentials.

If your code is more complex and requires multiple sub-modules, that is fine, as long as all the variables required to run the Template are defined somewhere in the root of the repository.

Variable Types

Whilst the examples above only used string types, all Terraform variable types are supported. Depending on the variable type specified, the Deployment form will adapt to the inputs required.

Providing User Selectable Options

Terraform variables are not able to provide lists of options to users, Terraform was intended as an automation tool after all where fixed valies are passed in. Using ECS and ESH together augments Terraforms variable definition functionality and provides the ability to turn string and number type fields into lists of option. It also enables variables to be defaulted, hidden or presented as read-only enabling complete control of the end users Deployment form. Read more about this functionality here.

Versioning and Deployment Upgrades

As your Templates evolve, you might want to change them to address security concerns, or add more features. This is catered for by Template versioning. As mentioned above, versioning is taken care of by Gits powerful tagging mechanism. When you make a change and want it to be usable by ESH, create a new tag, download it in ESH in the Template console, test it, and providing it meets your requirements, certify it.

Template Certification

Only one Template version can be certified. When a version is certified, it becomes the default version for all new deployments. If a user were to re-deploy their Deployment, the latest certified version would be used in the new deployment.