Develops Custom DevOps-Friendly Provider For Terraform

This is a guest post by Clément Contini, Cloud System Administrator for is a HashiCorp technology partner and provides Canadian regional cloud infrastructure for companies who have data sovereignty requirements. works as a standalone IaaS platform, or can be part of a hybrid or multi-cloud solution.

The team has developed a purpose-built provider for HashiCorp Terraform, making it possible to automate infrastructure deployments on the platform. Terraform is one of the numerous open-source tools for infrastructure management available from HashiCorp. It provides a DevOps-friendly approach to deploying complex IaaS environments, enabling increased agility and flexibility, particularly when it involves re-use of existing deployment architectures. You can download the provider here:

Apache CloudStack serves as the underlying orchestration platform for While it has a generic Terraform provider (which we wrote about here), we knew we could provide more value for our users by developing our own. This custom provider is more aligned with the design of our platform and specific deployment options, meaning users can automate capabilities via their Terraform configuration. For example, we simplify the use of CloudStack projects, a parameter that otherwise needs to be provided repeatedly when using the generic CloudStack provider. As an additional benefit, a single user can have access to manage multiple environments in an organization via Terraform, using the same credentials, if permissions allow it.

Another aspect that the provider covers that cannot be done with the generic CloudStack provider is the ability to control the “management” layer using the “environment” resource. You can specify the details of the role-based access control for each user in the Terraform configuration and/or even create new environments.

»Configuring a environment

Let’s take a look at a real configuration made for the provider, available in the following repository: This configuration will create an environment and a VPC with 3 networks. One network will be used for the front-end machines, one for the back-end machines and the last one for a utility machine.

All available variables are gathered in a file called “” and represent all the customization that can be applied on the configuration. Here is an excerpt of the file:

# Provider credentials
variable "api_key" {}
# General variables
variable "is_production" {}
variable "frontend_count" {}
variable "backend_count" {}
# Environment
variable "service_code" {}
variable "organization_code" {}
variable "environment_name" {}
variable "environment_description" {
  default = "Environment for %s workloads"
variable "admin" {
  type = "list"
variable "read_only" {
  type = "list"
variable "database_ports" {
  default = [ 3306 ]
variable "web_ports" {
  default = [ 80, 443 ]

To begin to use this configuration, create a file “terraform.tfvars” with all the variables that don’t have a default in “”. This might be things such as API keys, a list of users the organization wants to add to the environment, a list of required attributes specified in a README file, or variables to override. An example of this might be if you want to open port 8080 instead of 80 and 443, just add this to “terraform.tfvars”

web_ports = [ 8080 ]

And to specify role accesses:

admin_role = [ "clement", "mike" ]
read_only_role = [ ]

Now take a look at “”. It configures a “cloudca_environment” which takes a list of users in “admin_role” and “read_only_role”. These roles have to be specified in the “terraform.tfvars” file (no default is provided, you need to use the users from your own organization).

resource "cloudca_environment" "default" {
  service_code      = "${var.service_code}"
  organization_code = "${var.organization_code}"
  name              = "${var.environment_name}"
  description       = "${format("${var.environment_description}", "${var.environment_name}")}"
  admin_role        = ["${var.admin}"]
  read_only_role    = ["${var.read_only}"]

This also means that if you have several similar environments, let’s say a production environment and a development environment, you can use the same configuration for both of them and just change the variables “admin” and “read_only” to the appropriate values to limit the access to the production environment but enable full access on the development one.

One of the required variables in “terraform.tfvars” is the boolean “is_production”. When set to true, the ACL rules are stricter:

  • SSH access is opened only from the utility VM
  • The front-end is whitelisted to access the database network, everything else is denied

For example, the following piece of code handles ACL rules creation for the database network:

resource "cloudca_network_acl_rule" "db_allow_in_ports" {
  environment_id = "${}"
  count          = "${var.is_production ? var.frontend_count * length(var.database_ports) : 1}"

  rule_number    = "${10 + count.index + 1}"
  action         = "Allow"
  protocol       = "TCP"
  start_port     = "${element(var.database_ports, count.index % length(var.database_ports))}"

  end_port       = "${element(var.database_ports, count.index % length(var.database_ports))}"

  cidr           = "${var.is_production ? 
"${element(cloudca_instance.web_instance.*.private_ip, count.index)}/32" : "" }"

  traffic_type   = "Ingress"
  network_acl_id = "${}"

Depending if the environment is for production or not, the CIDR of the ACL will be different: open to for the development environment, extracted from the instances of the web network for production. The ports are also configurable and are selected from the list provided as variables.

»Integration with platform tools

The Terraform provider directly leverages built-in features of the platform, such as the activity log. Any action performed while using the Terraform provider will show up in the activity view. If you deploy the example configuration, you will see the different actions as they are performed:

Example of activity log on

We are continuously improving and developing the Terraform provider. An upcoming near-term roadmap item will provide the ability to export a Terraform configuration from an existing environment. This way, if the environment had been built manually but the user wants to reproduce it easily (in terms of infrastructure layout), it would be possible to simply press a button, get the Terraform configuration, and use it to create a similar environment.

In conclusion, we think Terraform is an excellent tool to use with

  • It enables automation using powerful, open source software.
  • It enables semi-automatic scaling, in the sense that it becomes very easy to change the number of instances of the same type when your needs change, through simple adjustments in the resource definition, making horizontal scaling simple and fast.
  • It enables users to automate the deployment of their environments and the associated user permissions.
  • It enables users to standardize their deployments and reuse configuration across them.
  • It can be used on to deploy the same environment in different zones, for example, to aid in creating geographically diverse or disaster recovery scenarios.
  • As a complement, application configuration can be orchestrated using tools like Chef or Docker, allowing for easy deployment of containers and making it an ideal tool for deploying cloud-native applications.

HashiCorp Terraform is a product to provision any infrastructure for any application. Terraform provides infrastructure as code, cloud platform management, and self-service infrastructure. To learn more about HashiCorp Terraform visit

Sign up for the latest HashiCorp news

By submitting this form, you acknowledge and agree that HashiCorp will process your personal information in accordance with the Privacy Policy.