Making it simpler to deploy IBM Cloud databases with Terraform

Building Blueprints and Guardrails for IBM Cloud
AUTHOR
Chris Reuter
PUBLISH DATE
September 10, 2024

Resourcely recently announced support for IBM Cloud’s Terraform provider. With it, anyone can create paved roads for IBM Cloud resources.

  • Make it easier and faster for developers to deploy IBM Cloud infrastructure
  • Expand and scale your infrastructure adoption
  • Govern the resources that are being deployed
  • Ensure your cloud platform is stable and secure
  • Reduce cloud infrastructure costs and waste

In this demo, we’ll take this example from the IBM Cloud Terraform database resource and turn it into a flexible Blueprint with attached Guardrails. Developers can choose from Blueprints, fill out a guided form, which will then automatically generate Terraform and submit a PR on their behalf to create infrastructure.

You can follow along in this clickable demo, or skip ahead to the instructions below. The Resourcely docs are also a wealth of information for how to customize your own Blueprints.

Clickable Demo

Blueprint structure

First, we’ll at the Terraform code and turn each field that we want developers to be able to input into {{ variables }}.

Blueprint
Copy
resource "ibm_database" "__name" {
  resource_group_id            = {{ resource_group | links_to: resource.ibm_resource_group.id | desc: "Select your IBM resource group ID from the dropdown, or type your own manually. If you don't know what this is, add a Resource Group to your PR from the shopping cart." }}
  name                         = {{ name | desc: "Name of your database. No spaces." }}
  service                      = {{ service | default: "databases-for-mongodb" | desc: "The type of database to instantiate" }}
  plan                         = {{ plan | default: "standard" | desc: "Service plan, all databases use standard except for Elasticsearch and mongoDB" }}
  location                     = {{ location | default: "us-south" | desc: "The IBM Cloud region. This defaults to us-south, you'll need to request permission via the Guardrail to change" }}
  adminpassword                = {{ admin_password | desc: "Admin password for the database." }}

  group {
    group_id = "database-settings"

    memory {
      allocation_mb = {{ allocation_mb_memory }}
    }

    disk {
      allocation_mb = {{ allocation_mb_disk }}
    }

    cpu {
      allocation_count = {{ allocation_cpu }}
    }
  }

{{# db_users }}
  users {
    name      = {{ db_users.name | required: false }}
    password  = {{ db_users.password | required: false }}
    type      = {{ db_users.type | required: false }}
  }
{{/ db_users}}

{{# allowlist }}
  allowlist {
    address     = {{ allowlist.address | desc: "Must be in format 1.2.3.4/32" | required: false }}
    description = {{ allowlist.description | required: false }}
  }
{{/ allowlist }}

  timeouts {
    create = {{ timeouts_create | desc: "Ex: 120m" | advanced: true }}
    update = {{ timeouts_update | desc: "Ex: 100m" | advanced: true }}
    delete = {{ timeouts_delete | desc: "Ex: 15m" | advanced: true }}
  }

Variable tags and parameters

You can see above that this is generally structured as Terraform, but with {{ variable }} tags and parameters (desc, default, required, links_to, etc.). Each {{ variable }} tag will automatically take an input in the resulting form developers interact with.

{{ variable }} tags include some automated quality-of-life features, including automatic suggestions for properties. Take the service variable above. The form automatically surfaces the various services available for the database resource.

This allows our developers the flexibility to choose the type of database that they want to deploy.

desc and default will provide hints for developers, while required allows us to make inputs optional. links_to gives us the ability to search for existing resources OR resources that are being created by the developer.

IBM Cloud databases are required to be associated with a resource_group, so we add a resource_group_id with a links_to tag. This manifests as a dropdown with available groups:

This is especially helpful for security groups, VPCs, IAM, or anywhere that developers want to use an existing resource.

Variables and groups sections

You will also notice that IBM Databases utilize a group object where we have no obvious tag parameters:

Blueprint
Copy
  group {
    group_id = "database-settings"

    memory {
      allocation_mb = {{ allocation_mb_memory }}
    }

    disk {
      allocation_mb = {{ allocation_mb_disk }}
    }

    cpu {
      allocation_count = {{ allocation_cpu }}
    }
  }

Group is for setting database infrastructure sizing. We have utilized Resourcely’s variables and groups sections to better organize these inputs, and Guardrails to put limits around how much infrastructure can be used.

Blueprint
Copy
---
constants:
  __name: "{{ name }}_{{ __guid }}"
variables:
  allocation_mb_memory:
    desc: "Database memory in MB. Higher than 128,000 (128GB) will route for exception approval."
    required: true
    group: Database sizing
    default: 64000
  allocation_mb_disk:
    desc: "Database storage in MB. Higher than 1,000,000 (1TB) will route for exception approval."
    required: true
    group: Database sizing
    default: 10000
  allocation_cpu:
    desc: "Database CPUs. Higher than 16 CPUs will route for exception approval."
    required: true
    group: Database sizing
    default: 8
  db_users:
    group: Optional database users
    required: false
  allowlist:
    group: Optional allowlists
    required: false
groups:
  Database sizing:
    order: 1
    desc: "Required sizing options for the database"
  Optional database users:
    order: 2
    desc: "Adding optional database users"
  Optional allowlists:
    order: 3
    desc: "Optionally define IP addresses that can access the database" 
---

Note that these sections belong at the top of your Blueprints, and are totally optional.

Guardrails for limiting cost

We’ve written the following Guardrails to enforce the amounts we put in the descriptions:

Guardrail
Copy
GUARDRAIL "Limit IBM database CPU size"
  WHEN ibm_database
    REQUIRE group.cpu.allocation_count <= 16
  OVERRIDE WITH APPROVAL @default

GUARDRAIL "Limit IBM database storage size"
  WHEN ibm_database
    REQUIRE group.disk.allocation_mb <= 1000000
  OVERRIDE WITH APPROVAL @default

GUARDRAIL "Limit IBM database memory size"
  WHEN ibm_database
    REQUIRE group.memory.allocation_mb <= 128000
  OVERRIDE WITH APPROVAL @default

GUARDRAIL "Limit IBM Database location"
  WHEN ibm_database
    REQUIRE location = "us-south"
  OVERRIDE WITH APPROVAL @default

GUARDRAIL "Limit IBM Database plan"
  WHEN ibm_database
    REQUIRE plan = "standard"
  OVERRIDE WITH APPROVAL @default

This results in Guardrail locks when the developer is configuring their infrastructure. Let’s say they want 24 CPUs. They can request approval from the default approver group by unlocking the Guardrail.

This gives developers feedback at configuration time, and also makes sure that any PR that is generated goes to the right approver.

Section tags

Finally, IBM Cloud databases have the ability to add multiple users or access rules. We use the {{# variable }} {{/ variable }} syntax to allow creation of multiple objects with the same structure. Here is an example from our Blueprint:

Blueprint
Copy
{{# db_users }}
  users {
    name      = {{ db_users.name | required: false }}
    password  = {{ db_users.password | required: false }}
    type      = {{ db_users.type | required: false }}
  }
{{/ db_users}}

This results in a section tag like the below, where developers can create multiple db_users:

Resulting form

After all of our Blueprint customization, the following form is made available to developers that want to deploy a database:

This form for deploying a database on IBM Cloud gives developers choices, obfuscates other non-critical properties, and governs the choices that developers are making.

Once they fill the PR form out, Terraform is generated and a PR automatically submitted to your change management!

Summary

We built a paved road for deploying databases, starting from a purpose-built example for MongoDB and finishing with a flexible form that supports all of the provider’s settings while giving developers guidance and sensible defaults.

Blueprints are a great alternative to Terraform modules for deploying databases, while Guardrails allow you to tightly govern database configuration.

Get started with Resourcely yourself today!

Ready to get started?

Set up a time to talk to our team to get started with Resourcely.

Get in touch

More posts

View all
July 24, 2024

A deep dive into Blueprints

Building a paved road to production for AWS EC2
September 27, 2024

Incident Review: The Arc Browser Vulnerability

How you can prevent Firebase misconfiguration
October 31, 2024

Creating an IAM factory featuring AWS IAM

Give developers a flexible, guided form for configuring and deploying IAM

Talk to a Human

See Resourcely in action and learn how it can help you secure and manage your cloud infrastructure today!