Terraform on Brightbox Cloud

Terraform is a tool to make managing your overall system infrastructure as easy as managing your individual server configuration. You map out all the different components of your systems from as many different providers as you need and represent them all in code. Terraform handles working out all the dependencies, building the components and configuring all the relationships.

It’s focused very much on infrastructure, so once everything is built the baton is passed onto your configuration management tool of choice, such as Puppet, Chef or Ansible. Terraform just handles orchestrating the bootstrapping.

The result is a detailed description of everything you need to build your entire system from scratch.

Brightbox has written a Terraform provider plugin to add support for managing Brightbox Cloud resources via our API.

This guide will take you through installing Terraform on your local machine and building a small cluster with it using a basic example configuration.

Install Terraform

There are detailed instructions on installing Terraform in their own getting started guide, but the general idea is to download the appropriate package and unzip the binaries to somewhere in your shell’s PATH.

If you’re using Linux or similar, you could unzip them into your system-wide /usr/local/bin directory. Or you can put them somewhere in your home directory and add that to your PATH variable. E.g:

$ wget -q
$ sudo unzip -d /usr/local/bin/

  inflating: /usr/local/bin/terraform  
  inflating: /usr/local/bin/terraform-provider-atlas  
  inflating: /usr/local/bin/terraform-provider-chef  
  inflating: /usr/local/bin/terraform-provider-cloudflare  
  inflating: /usr/local/bin/terraform-provider-cloudstack  
  inflating: /usr/local/bin/terraform-provider-consul  
  inflating: /usr/local/bin/terraform-provider-datadog  
  inflating: /usr/local/bin/terraform-provider-mysql  

Install the Brightbox Terraform Provider

You can find the latest Brightbox Terraform provider binaries on the github releases page.

Again, find the appropriate package for your architecture and run the installation process

$ mkdir /tmp/provider
$ cd /tmp/provider
$ wget -q
$ tar xvf terraform-provider-brightbox_0.1.2_linux_amd64.tar.gz
$ ./

This copies the provider into the terraform plugin search path. To get terraform to pick up the provider make sure you run terraform init in your terraform configuation directory

Clone our example Terraform configuration

Our example Terraform configuration defines a cloud server and a cloud sql instance, plus cloud ips and appropriate firewall rules for them.

Get the example configuration from our GitHub repository:

git clone
cd terraform-brightbox-example

Setup authentication

Terraform authenticates with Brightbox using your username and password, plus you need to specify which of your accounts you want it work with (if you’ve not collaborated on any other accounts, you’ll have only one but you still need to specify the id).

You can configure your credentials either by editing the file and specifying everything there, or you can avoid writing credentials to disk and set them as environment variables:

export BRIGHTBOX_ACCOUNT=acc-xxxxx
export BRIGHTBOX_PASSWORD=mysecretpassword

Activate the brightbox plugin

Before using a configuration initialise terraform so that it knows about the Brightbox provider plugin

$ terraform init

Execution plan

Now you have the example configuration checked out and your authentication configured, you can get terraform to show you its execution plan:

$ terraform init
$ terraform plan
Refreshing Terraform state prior to plan...

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ brightbox_cloudip.db
    name:        "" => "db ip"
    target:      "" => "${}"

+ brightbox_cloudip.webip
    name:        "" => "web ip"
    target:      "" => "${brightbox_server.webserver.interface}"

+ brightbox_database_server.db
    database_engine:     "" => "mysql"
    database_version:    "" => "5.6"
    maintenance_hour:    "" => "2"
    maintenance_weekday: "" => "6"
    name:                "" => "db server"

+ brightbox_firewall_policy.webservers
    name:         "" => "web servers"
    server_group: "" => "${}"

+ brightbox_firewall_rule.webservers_outbound
    description:     "" => "Outbound internet access"
    destination:     "" => "any"
    firewall_policy: "" => "${}"

+ brightbox_firewall_rule.webservers_ssh
    description:      "" => "SSH access from anywhere"
    destination_port: "" => "22"
    firewall_policy:  "" => "${}"
    protocol:         "" => "tcp"
    source:           "" => "any"

+ brightbox_firewall_rule.webservers_web
    description:      "" => "HTTP/S access from anywhere"
    destination_port: "" => "80,443"
    firewall_policy:  "" => "${}"
    protocol:         "" => "tcp"
    source:           "" => "any"

+ brightbox_server.webserver
    image:                "" => "img-hp57r"
    name:                 "" => "web server"

+ brightbox_server_group.webservers
    name: "" => "web servers"

Plan: 9 to add, 0 to change, 0 to destroy.


The plan looks good so let’s actually create the cluster. Just run terraform apply:

$ terraform apply
brightbox_server_group.webservers: Creating...
  name: "" => "web servers"
brightbox_server_group.webservers: Creation complete
brightbox_server.webserver: Creating...
  image:                    "" => "img-8pcus"
  name:                     "" => "web server"
  server_groups.#:          "" => "1"
  server_groups.3292108263: "" => "grp-q7yjw"
brightbox_firewall_policy.webservers: Creating...
  name:         "" => "web servers"
  server_group: "" => "grp-q7yjw"
brightbox_database_server.db: Creating...
  admin_password:          "" => "<computed>"
  admin_username:          "" => "<computed>"
  allow_access.#:          "" => "1"
  allow_access.3292108263: "" => "grp-q7yjw"
  database_engine:         "" => "mysql"
  database_version:        "" => "5.6"
  maintenance_hour:        "" => "2"
  maintenance_weekday:     "" => "6"
  name:                    "" => "db server"
brightbox_firewall_policy.webservers: Creation complete
brightbox_firewall_rule.webservers_outbound: Creating...
  description:     "" => "Outbound internet access"
  destination:     "" => "any"
  firewall_policy: "" => "fwp-hdt8p"
brightbox_firewall_rule.webservers_web: Creating...
  description:      "" => "HTTP/S access from anywhere"
  destination_port: "" => "80,443"
  firewall_policy:  "" => "fwp-hdt8p"
  protocol:         "" => "tcp"
  source:           "" => "any"
brightbox_firewall_rule.webservers_ssh: Creating...
  description:      "" => "SSH access from anywhere"
  destination_port: "" => "22"
  firewall_policy:  "" => "fwp-hdt8p"
  protocol:         "" => "tcp"
  source:           "" => "any"
brightbox_firewall_rule.webservers_web: Creation complete
brightbox_firewall_rule.webservers_ssh: Creation complete
brightbox_firewall_rule.webservers_outbound: Creation complete
brightbox_server.webserver: Creation complete
brightbox_cloudip.webip: Creating...
  name:        "" => "web ip"
  target:      "" => "int-q9u2e"
brightbox_cloudip.webip: Creation complete
brightbox_database_server.db: Creation complete
brightbox_cloudip.db: Creating...
  name:        "" => "db ip"
  target:      "" => "dbs-mop1a"
brightbox_cloudip.db: Creation complete

Apply complete! Resources: 9 added, 0 changed, 0 destroyed.

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate


  db admin account password = sw60sfhaeo5w6evk
  db ip address             =
  web public ip address     =

Specify your own image id

The example config will build the server using an Ubuntu Trusty server image, but you can specify your own. Either edit the file to specify the image_id terraform variable, or provide it manually when running the apply command like this:

$ terraform apply -var "image_id=img-xxxxx"

Test it

To demonstrate that everything has been set up and linked together correct, test the MySQL connection from the new cloud server to the new cloud sql instance. Use the DNS names and password details from the Outputs section above:

$ ssh -l ubuntu

ubuntu@srv-s4na0:~$ sudo apt-get update -qq
ubuntu@srv-s4na0:~$ sudo apt-get install -qq -y mysql-client

ubuntu@srv-s4na0:~$ mysql -h -u admin -p
Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 70
Server version: 5.6.29-76.2-log Percona Server (GPL), Release 76.2, Revision ddf26fe

mysql> show status like 'Uptime';
| Variable_name | Value |
| Uptime        | 378   |
1 row in set (0.00 sec)


Terraform state data

Terraform keeps track of what resources it creates and their attributes in a state file named terraform.tfstate in the current directory. This is required for terraform to continue to manage your cluster, so keep it safe.

For each new cluster you want to manage, just create a new directory with a copy of your configs in.


If this was a real cluster, you’d obviously need to configure your new cloud server and deploy your app to it. These steps are usually best left to configuration management tools like Puppet, Ansible or Chef but Terraform can be told how to execute these once the server is online. See their Terraform documentation on provisioners for more details.

Destroy it

Since this is just a test cluster, you can tear it all down now. Just run terraform destroy and it’ll destroy just those resources that it created as part of this example.

$ terraform destroy
Do you really want to destroy?
  Terraform will delete all your managed infrastructure.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

brightbox_server_group.webservers: Refreshing state... (ID: grp-q7yjw)
brightbox_database_server.db: Refreshing state... (ID: dbs-mop1a)
brightbox_server.webserver: Refreshing state... (ID: srv-s4na0)
brightbox_firewall_policy.webservers: Refreshing state... (ID: fwp-hdt8p)
brightbox_cloudip.db: Refreshing state... (ID: cip-bjj4c)
brightbox_firewall_rule.webservers_ssh: Refreshing state... (ID: fwr-6gr0o)
brightbox_firewall_rule.webservers_outbound: Refreshing state... (ID: fwr-omtji)
brightbox_firewall_rule.webservers_web: Refreshing state... (ID: fwr-vdizj)
brightbox_cloudip.webip: Refreshing state... (ID: cip-crl7w)
brightbox_cloudip.webip: Destroying...
brightbox_cloudip.db: Destroying...
brightbox_firewall_rule.webservers_web: Destroying...
brightbox_firewall_rule.webservers_outbound: Destroying...
brightbox_firewall_rule.webservers_ssh: Destroying...
brightbox_firewall_rule.webservers_outbound: Destruction complete
brightbox_firewall_rule.webservers_web: Destruction complete
brightbox_firewall_rule.webservers_ssh: Destruction complete
brightbox_firewall_policy.webservers: Destroying...
brightbox_firewall_policy.webservers: Destruction complete
brightbox_cloudip.webip: Destruction complete
brightbox_server.webserver: Destroying...
brightbox_cloudip.db: Destruction complete
brightbox_database_server.db: Destroying...
brightbox_server.webserver: Destruction complete
brightbox_database_server.db: Destruction complete
brightbox_server_group.webservers: Destroying...
brightbox_server_group.webservers: Destruction complete

If you’d rather not completely trust Terraform, remember you can use our “resource lock” feature to prevent accidental deletions of important resources.

Last updated: 20 Jun 2018 at 10:51 UTC

Try Brightbox risk-free with £20 free credit Sign up takes just two minutes...